Skip to content

Commit 9b9a7cd

Browse files
committed
[Scene] Add Z-ordering and event cancellation
1 parent 85ee489 commit 9b9a7cd

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

src/scene/include/growl/scene/node.h

+17-1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ class Node : public InputProcessor, public Entity {
7575

7676
void setClickListener(std::function<bool(float, float)> listener);
7777

78+
// A higher Z priority means the node will be drawn later in the order
79+
// of children.
80+
void setZPriority(float z);
81+
7882
protected:
7983
Node* getParent() {
8084
return parent;
@@ -99,6 +103,15 @@ class Node : public InputProcessor, public Entity {
99103
virtual bool onControllerEvent(const InputControllerEvent& event) override;
100104
bool onControllerEventRaw(const InputControllerEvent& event);
101105

106+
bool clickListenerDown() {
107+
return click_listener_down;
108+
}
109+
std::function<bool(float x, float y)>& getClickListener() {
110+
return click_listener;
111+
}
112+
113+
void cancelEvent();
114+
102115
private:
103116
API* api;
104117
std::unique_ptr<Script> script;
@@ -109,22 +122,25 @@ class Node : public InputProcessor, public Entity {
109122
float w = 0;
110123
float h = 0;
111124
float rotation = 0;
125+
float z = 0;
112126
std::vector<std::unique_ptr<Node>> children;
127+
std::vector<Node*> children_z_order;
113128
glm::mat4x4 local_transform;
114129
std::unique_ptr<ScriptingRef> bound_script_obj = nullptr;
115130
DebugRendering debug_rendering = DebugRendering::OFF;
116131
bool debug_mouseover = false;
117132
int depth = 0;
118133
std::optional<Color> color;
119-
120134
std::function<bool(float x, float y)> click_listener;
121135
bool click_listener_down = false;
136+
bool event_cancelled = false;
122137

123138
void computeLocalTransform();
124139
void drawChildren(Batch& batch, float parent_alpha);
125140
void populateDebugUI(Batch& batch);
126141
void setDepth(int depth);
127142
bool processClick(float x, float y, PointerEventType type);
143+
void reorderZ();
128144
};
129145

130146
} // namespace Growl

src/scene/src/node.cpp

+37-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "growl/core/input/event.h"
88
#include "growl/core/scripting/script.h"
99
#include "growl/scene/scene.h"
10+
#include <algorithm>
1011
#include <string>
1112
#ifdef GROWL_IMGUI
1213
#include "glm/ext/scalar_constants.hpp"
@@ -40,15 +41,22 @@ Node* Node::addChild(std::unique_ptr<Node> node) {
4041
children.emplace_back(std::move(node));
4142
Node* n = children.back().get();
4243
n->setDepth(depth + 1);
44+
children_z_order.emplace_back(n);
4345
return n;
4446
}
4547

4648
void Node::removeChild(int i) {
4749
children.erase(std::next(children.begin(), i));
50+
children_z_order.clear();
51+
for (auto& child : children) {
52+
children_z_order.emplace_back(child.get());
53+
}
54+
reorderZ();
4855
}
4956

5057
void Node::clear() {
5158
children.clear();
59+
children_z_order.clear();
5260
}
5361

5462
void Node::setDepth(int depth) {
@@ -167,7 +175,7 @@ void Node::draw(Batch& batch, float parent_alpha) {
167175
}
168176

169177
void Node::onDraw(Batch& batch, float parent_alpha, glm::mat4x4 transform) {
170-
for (auto& child : children) {
178+
for (auto child : children_z_order) {
171179
child->draw(batch, parent_alpha);
172180
}
173181
}
@@ -176,13 +184,31 @@ void Node::setClickListener(std::function<bool(float, float)> listener) {
176184
this->click_listener = std::move(listener);
177185
}
178186

187+
void Node::setZPriority(float z) {
188+
this->z = z;
189+
if (this->parent) {
190+
this->parent->reorderZ();
191+
}
192+
}
193+
194+
void Node::cancelEvent() {
195+
event_cancelled = true;
196+
if (parent) {
197+
parent->cancelEvent();
198+
}
199+
}
200+
179201
bool Node::onEvent(const InputEvent& event) {
180202
if (InputProcessor::onEvent(event)) {
181203
return true;
182204
}
183205
bool handled = false;
206+
this->event_cancelled = false;
184207
for (auto& child : children) {
185208
handled |= child->onEvent(event);
209+
if (this->event_cancelled) {
210+
break;
211+
}
186212
}
187213
return onPostEvent(event, handled);
188214
}
@@ -240,6 +266,12 @@ void Node::computeLocalTransform() {
240266
}
241267
}
242268

269+
void Node::reorderZ() {
270+
std::stable_sort(
271+
children_z_order.begin(), children_z_order.end(),
272+
[](const Node* a, const Node* b) -> bool { return a->z < b->z; });
273+
}
274+
243275
bool Node::onMouseEvent(const InputMouseEvent& event) {
244276
if (!bound_script_obj) {
245277
return onMouseEventRaw(event);
@@ -410,7 +442,11 @@ bool Node::processClick(float x, float y, PointerEventType type) {
410442
default:
411443
return false;
412444
}
445+
} else if (type == PointerEventType::Move) {
446+
// Move outside, cancel click
447+
click_listener_down = false;
413448
}
449+
414450
if (type == PointerEventType::Up) {
415451
click_listener_down = false;
416452
}

0 commit comments

Comments
 (0)