TDME2  1.9.200
GUIElementController.cpp
Go to the documentation of this file.
2 
3 #include <string>
4 
5 #include <tdme/tdme.h>
11 #include <tdme/gui/nodes/GUINode.h>
14 #include <tdme/gui/GUI.h>
15 #include <tdme/math/Math.h>
16 #include <tdme/utilities/Console.h>
17 #include <tdme/utilities/Time.h>
18 
19 using std::string;
20 using std::to_string;
21 
31 using tdme::gui::GUI;
32 using tdme::math::Math;
35 
36 GUIElementController::GUIElementController(GUINode* node)
37  : GUINodeController(node)
38 {
39  this->isActionPerforming = false;
40  this->disabled = required_dynamic_cast<GUIElementNode*>(node)->isDisabled();
41  this->initialized = false;
42 }
43 
46 
48 {
49  return disabled;
50 }
51 
53 {
54  auto& nodeConditions = required_dynamic_cast<GUIElementNode*>(node)->getActiveConditions();
55  nodeConditions.remove(this->disabled == true?CONDITION_DISABLED:CONDITION_ENABLED);
56  this->disabled = disabled;
57  nodeConditions.add(this->disabled == true?CONDITION_DISABLED:CONDITION_ENABLED);
58  isActionPerforming = false;
59 }
60 
62 {
63  this->node->getScreenNode()->addTickNode(this->node);
65 }
66 
68 {
69 }
70 
72 {
73 }
74 
76 {
77  if (disabled == true) return;
78  auto elementNode = required_dynamic_cast<GUIElementNode*>(this->node);
79  if (node == elementNode && elementNode->isEventBelongingToNode(event) == true && event->getButton() == MOUSE_BUTTON_LEFT) {
80  if (event->getType() == GUIMouseEvent::MOUSEEVENT_PRESSED) {
81  elementNode->getActiveConditions().add(GUIElementNode::CONDITION_CLICK);
82  isActionPerforming = true;
83  if (elementNode->isFocusable() == true) {
84  node->getScreenNode()->getGUI()->setFoccussedNode(elementNode);
85  }
86  mouseLastX = event->getXUnscaled();
87  mouseLastY = event->getYUnscaled();
88  event->setProcessed(true);
89  } else
90  if (event->getType() == GUIMouseEvent::MOUSEEVENT_DRAGGED) {
91  isActionPerforming = true;
92  //
93  if (Math::abs(mouseLastX - event->getX()) > 7 ||
94  Math::abs(mouseLastY - event->getY()) > 7) {
95  node->getScreenNode()->forwardDragRequest(elementNode, event->getXUnscaled(), event->getYUnscaled());
96  }
97  } else
98  if (event->getType() == GUIMouseEvent::MOUSEEVENT_RELEASED) {
99  elementNode->getActiveConditions().remove(GUIElementNode::CONDITION_CLICK);
100  isActionPerforming = false;
101  auto now = Time::getCurrentMillis();
102  if (timeLastClicked != -1LL) {
103  if (now - timeLastClicked < TIME_DOUBLECLICK) {
104  auto onMouseDoubleClickExpression = elementNode->getOnMouseDoubleClickExpression();
105  if (onMouseDoubleClickExpression.size() > 0) {
106  GUIElementNode::executeExpression(elementNode->getScreenNode(), onMouseDoubleClickExpression);
107  } else {
108  auto onMouseClickExpression = elementNode->getOnMouseClickExpression();
109  if (onMouseClickExpression.size() > 0) GUIElementNode::executeExpression(elementNode->getScreenNode(), onMouseClickExpression);
111  }
112  timeLastClicked = -1LL;
113  } else {
114  auto onMouseClickExpression = elementNode->getOnMouseClickExpression();
115  if (onMouseClickExpression.size() > 0) GUIElementNode::executeExpression(elementNode->getScreenNode(), onMouseClickExpression);
117  timeLastClicked = -1LL;
118  }
119  } else {
120  auto onMouseDoubleClickExpression = elementNode->getOnMouseDoubleClickExpression();
121  if (onMouseDoubleClickExpression.size() > 0) {
122  timeLastClicked = now;
123  } else {
124  auto onMouseClickExpression = elementNode->getOnMouseClickExpression();
125  if (onMouseClickExpression.size() > 0) GUIElementNode::executeExpression(elementNode->getScreenNode(), onMouseClickExpression);
127  }
128  }
129  //
130  mouseLastX = -1;
131  mouseLastY = -1;
132  event->setProcessed(true);
133  }
134  } else
135  if (node == elementNode && elementNode->isEventBelongingToNode(event) == true && event->getButton() == MOUSE_BUTTON_RIGHT) {
136  if (event->getType() == GUIMouseEvent::MOUSEEVENT_PRESSED) {
137  node->getScreenNode()->forwardContextMenuRequest(elementNode, event->getXUnscaled(), event->getYUnscaled());
138  }
139  event->setProcessed(true);
140  } else
141  if (node == elementNode && event->getType() == GUIMouseEvent::MOUSEEVENT_RELEASED && event->getButton() == MOUSE_BUTTON_LEFT && elementNode->getActiveConditions().has(GUIElementNode::CONDITION_CLICK)) {
142  elementNode->getActiveConditions().remove(GUIElementNode::CONDITION_CLICK);
143  event->setProcessed(true);
144  } else
145  if (event->getType() == GUIMouseEvent::MOUSEEVENT_MOVED) {
146  if (elementNode->isEventBelongingToNode(event) == true) {
147  if (elementNode->getOptionValue("mouse-cursor") == "hand") Application::setMouseCursor(MOUSE_CURSOR_HAND);
148  node->getScreenNode()->forwardMouseOver(elementNode);
149  elementNode->getActiveConditions().add(GUIElementNode::CONDITION_ONMOUSEOVER);
151  auto onMouseOverExpression = elementNode->getOnMouseOverExpression();
152  if (onMouseOverExpression.size() > 0) GUIElementNode::executeExpression(elementNode->getScreenNode(), onMouseOverExpression);
153  } else {
154  if (elementNode->getOptionValue("mouse-cursor") == "hand") Application::setMouseCursor(MOUSE_CURSOR_NORMAL);
155  elementNode->getActiveConditions().remove(GUIElementNode::CONDITION_ONMOUSEOVER);
156  auto onMouseOutExpression = elementNode->getOnMouseOutExpression();
157  if (onMouseOutExpression.size() > 0) GUIElementNode::executeExpression(elementNode->getScreenNode(), onMouseOutExpression);
158  }
159  } else {
160  isActionPerforming = false;
161  }
162 }
163 
165 {
166  if (disabled == false) {
167  switch (event->getKeyCode()) {
168  case GUIKeyboardEvent::KEYCODE_SPACE: {
169  event->setProcessed(true);
170  if (event->getType() == GUIKeyboardEvent::KEYBOARDEVENT_KEY_PRESSED) {
171  auto onMouseClickExpression = required_dynamic_cast<GUIElementNode*>(node)->getOnMouseClickExpression();
172  if (onMouseClickExpression.size() > 0) GUIElementNode::executeExpression(node->getScreenNode(), onMouseClickExpression);
173  node->getScreenNode()->forwardAction(GUIActionListenerType::PERFORMED, required_dynamic_cast<GUIElementNode*>(node));
174  }
175  }
176  break;
177  default: {
178  break;
179  }
180  }
181  }
182 }
183 
185 {
186  if (initialized == false) {
187  auto onInitializeExpression = required_dynamic_cast<GUIElementNode*>(node)->getOnInitializeExpression();
188  if (onInitializeExpression.size() > 0) GUIElementNode::executeExpression(node->getScreenNode(), onInitializeExpression);
189  initialized = true;
190  // TODO: check me, the following code has performance relevance!!!
191  // auto onMouseClickExpression = required_dynamic_cast<GUIElementNode*>(node)->getOnMouseClickExpression();
192  // if (onMouseClickExpression.size() == 0) node->getScreenNode()->removeTickNode(node);
193  }
194 
195  auto now = Time::getCurrentMillis();
196  if (timeLastClicked != -1LL && now - timeLastClicked >= TIME_DOUBLECLICK) {
197  timeLastClicked = -1LL;
198  auto onMouseClickExpression = required_dynamic_cast<GUIElementNode*>(node)->getOnMouseClickExpression();
199  if (onMouseClickExpression.size() > 0) GUIElementNode::executeExpression(node->getScreenNode(), onMouseClickExpression);
200  node->getScreenNode()->forwardAction(GUIActionListenerType::PERFORMED, required_dynamic_cast<GUIElementNode*>(node));
201  }
202 
203  if (isActionPerforming == true) {
204  if (disabled == true) {
205  isActionPerforming = false;
206  return;
207  }
208  node->getScreenNode()->forwardAction(GUIActionListenerType::PERFORMING, required_dynamic_cast<GUIElementNode*>(node));
209  }
210 }
211 
213 {
214 }
215 
217 {
218 }
219 
221 {
222  return false;
223 }
224 
226 {
227  return value;
228 }
229 
231 {
232 }
233 
235 {
236 }
#define MOUSE_CURSOR_NORMAL
Definition: Application.h:13
#define MOUSE_CURSOR_HAND
Definition: Application.h:14
#define MOUSE_BUTTON_LEFT
#define MOUSE_BUTTON_RIGHT
Application base class, please make sure to allocate application on heap to have correct application ...
Definition: Application.h:41
GUI module class.
Definition: GUI.h:64
void addMouseOutCandidateNode(GUINode *node)
Add node that is a possible mouse out candidate as it received a mouse over.
Definition: GUI.h:317
void setFoccussedNode(GUIElementNode *newFoccussedNode)
Set focussed node.
Definition: GUI.cpp:267
GUIKeyboardEventType getType() const
GUIMouseEventType getType() const
Definition: GUIMouseEvent.h:78
void onFocusGained() override
On focus gained.
void dispose() override
Dispose controller.
void postLayout() override
Post layout event.
void initialize() override
Initialize controller after element has been created.
void handleKeyboardEvent(GUIKeyboardEvent *event) override
Handle keyboard event.
void onFocusLost() override
On focus lost.
void setValue(const MutableString &value) override
Set value.
void handleMouseEvent(GUINode *node, GUIMouseEvent *event) override
Handle mouse event.
void tick() override
Tick method will be executed once per frame.
static STATIC_DLL_IMPEXT string CONDITION_DISABLED
static STATIC_DLL_IMPEXT string CONDITION_ENABLED
void setDisabled(bool disabled) override
Set disabled.
const MutableString & getValue() override
void onSubTreeChange() override
On sub tree change.
static STATIC_DLL_IMPEXT string CONDITION_ONMOUSEOVER
static STATIC_DLL_IMPEXT string CONDITION_CLICK
static void executeExpression(GUIScreenNode *screenNode, const string &expression)
Execute expression.
GUI element node conditions.
GUI node controller base class.
GUI node base class.
Definition: GUINode.h:64
bool isEventBelongingToNode(GUIMouseEvent *event, Vector2 &nodeCoordinate)
Is event belonging to node.
Definition: GUINode.h:604
GUIScreenNode * getScreenNode()
Definition: GUINode.h:325
GUI screen node that represents a screen that can be rendered via GUI system.
Definition: GUIScreenNode.h:72
void forwardContextMenuRequest(GUIElementNode *node, int mouseX, int mouseY)
Forward context menu request event.
void forwardAction(GUIActionListenerType type, GUIElementNode *node)
Forward action event.
void forwardMouseOver(GUIElementNode *node)
Forward mouse over event.
void addTickNode(GUINode *node)
Add tick node, registered node controllers will have a tick once per frame.
void forwardDragRequest(GUIElementNode *node, int mouseX, int mouseY)
Forward drag request event.
Standard math functions.
Definition: Math.h:19
Console class.
Definition: Console.h:29
Mutable utf8 aware string class.
Definition: MutableString.h:23
Time utility class.
Definition: Time.h:20