Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/scene/gui/graph_element.cpp
9903 views
1
/**************************************************************************/
2
/* graph_element.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "graph_element.h"
32
33
#include "scene/gui/graph_edit.h"
34
#include "scene/theme/theme_db.h"
35
36
#ifdef TOOLS_ENABLED
37
void GraphElement::_edit_set_position(const Point2 &p_position) {
38
GraphEdit *graph = Object::cast_to<GraphEdit>(get_parent());
39
if (graph) {
40
Point2 offset = (p_position + graph->get_scroll_offset()) * graph->get_zoom();
41
set_position_offset(offset);
42
}
43
set_position(p_position);
44
}
45
#endif
46
47
void GraphElement::_resort() {
48
Size2 size = get_size();
49
50
for (int i = 0; i < get_child_count(); i++) {
51
Control *child = as_sortable_control(get_child(i));
52
if (!child) {
53
continue;
54
}
55
fit_child_in_rect(child, Rect2(Point2(), size));
56
}
57
}
58
59
Size2 GraphElement::get_minimum_size() const {
60
Size2 minsize;
61
for (int i = 0; i < get_child_count(); i++) {
62
Control *child = as_sortable_control(get_child(i), SortableVisibilityMode::IGNORE);
63
if (!child) {
64
continue;
65
}
66
67
Size2i size = child->get_combined_minimum_size();
68
69
minsize = minsize.max(size);
70
}
71
72
return minsize;
73
}
74
75
void GraphElement::_notification(int p_what) {
76
switch (p_what) {
77
case NOTIFICATION_SORT_CHILDREN: {
78
_resort();
79
} break;
80
81
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
82
case NOTIFICATION_TRANSLATION_CHANGED:
83
case NOTIFICATION_THEME_CHANGED: {
84
update_minimum_size();
85
queue_redraw();
86
} break;
87
}
88
}
89
90
void GraphElement::_validate_property(PropertyInfo &p_property) const {
91
if (!Engine::get_singleton()->is_editor_hint()) {
92
return;
93
}
94
GraphEdit *graph = Object::cast_to<GraphEdit>(get_parent());
95
if (graph) {
96
if (p_property.name == "position") {
97
p_property.usage |= PROPERTY_USAGE_READ_ONLY;
98
}
99
}
100
}
101
102
void GraphElement::set_position_offset(const Vector2 &p_offset) {
103
if (position_offset == p_offset) {
104
return;
105
}
106
107
position_offset = p_offset;
108
emit_signal(SNAME("position_offset_changed"));
109
queue_redraw();
110
}
111
112
Vector2 GraphElement::get_position_offset() const {
113
return position_offset;
114
}
115
116
void GraphElement::set_selected(bool p_selected) {
117
if (!is_selectable() || selected == p_selected) {
118
return;
119
}
120
selected = p_selected;
121
emit_signal(p_selected ? SNAME("node_selected") : SNAME("node_deselected"));
122
queue_redraw();
123
}
124
125
bool GraphElement::is_selected() {
126
return selected;
127
}
128
129
void GraphElement::set_drag(bool p_drag) {
130
if (p_drag) {
131
drag_from = get_position_offset();
132
} else {
133
emit_signal(SNAME("dragged"), drag_from, get_position_offset()); // Required for undo/redo.
134
}
135
}
136
137
Vector2 GraphElement::get_drag_from() {
138
return drag_from;
139
}
140
141
void GraphElement::gui_input(const Ref<InputEvent> &p_ev) {
142
ERR_FAIL_COND(p_ev.is_null());
143
144
Ref<InputEventMouseButton> mb = p_ev;
145
if (mb.is_valid()) {
146
ERR_FAIL_NULL_MSG(get_parent_control(), "GraphElement must be the child of a GraphEdit node.");
147
148
if (mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
149
Vector2 mpos = mb->get_position();
150
151
if (resizable && mpos.x > get_size().x - theme_cache.resizer->get_width() && mpos.y > get_size().y - theme_cache.resizer->get_height()) {
152
resizing = true;
153
resizing_from = mpos;
154
resizing_from_size = get_size();
155
accept_event();
156
return;
157
}
158
159
emit_signal(SNAME("raise_request"));
160
}
161
162
if (!mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
163
if (resizing) {
164
resizing = false;
165
emit_signal(SNAME("resize_end"), get_size());
166
return;
167
}
168
}
169
}
170
171
Ref<InputEventMouseMotion> mm = p_ev;
172
if (resizing && mm.is_valid()) {
173
Vector2 mpos = mm->get_position();
174
Vector2 diff = mpos - resizing_from;
175
176
emit_signal(SNAME("resize_request"), resizing_from_size + diff);
177
}
178
179
GraphEdit *graph = Object::cast_to<GraphEdit>(get_parent());
180
if (graph && has_focus()) {
181
graph->key_input(p_ev);
182
}
183
}
184
185
void GraphElement::set_resizable(bool p_enable) {
186
if (resizable == p_enable) {
187
return;
188
}
189
resizable = p_enable;
190
queue_redraw();
191
}
192
193
bool GraphElement::is_resizable() const {
194
return resizable;
195
}
196
197
void GraphElement::set_draggable(bool p_draggable) {
198
draggable = p_draggable;
199
}
200
201
bool GraphElement::is_draggable() {
202
return draggable;
203
}
204
205
void GraphElement::set_selectable(bool p_selectable) {
206
if (!p_selectable) {
207
set_selected(false);
208
}
209
selectable = p_selectable;
210
}
211
212
bool GraphElement::is_selectable() {
213
return selectable;
214
}
215
216
void GraphElement::_bind_methods() {
217
ClassDB::bind_method(D_METHOD("set_resizable", "resizable"), &GraphElement::set_resizable);
218
ClassDB::bind_method(D_METHOD("is_resizable"), &GraphElement::is_resizable);
219
220
ClassDB::bind_method(D_METHOD("set_draggable", "draggable"), &GraphElement::set_draggable);
221
ClassDB::bind_method(D_METHOD("is_draggable"), &GraphElement::is_draggable);
222
223
ClassDB::bind_method(D_METHOD("set_selectable", "selectable"), &GraphElement::set_selectable);
224
ClassDB::bind_method(D_METHOD("is_selectable"), &GraphElement::is_selectable);
225
226
ClassDB::bind_method(D_METHOD("set_selected", "selected"), &GraphElement::set_selected);
227
ClassDB::bind_method(D_METHOD("is_selected"), &GraphElement::is_selected);
228
229
ClassDB::bind_method(D_METHOD("set_position_offset", "offset"), &GraphElement::set_position_offset);
230
ClassDB::bind_method(D_METHOD("get_position_offset"), &GraphElement::get_position_offset);
231
232
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position_offset"), "set_position_offset", "get_position_offset");
233
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resizable"), "set_resizable", "is_resizable");
234
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draggable"), "set_draggable", "is_draggable");
235
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selectable"), "set_selectable", "is_selectable");
236
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selected"), "set_selected", "is_selected");
237
238
ADD_SIGNAL(MethodInfo("node_selected"));
239
ADD_SIGNAL(MethodInfo("node_deselected"));
240
241
ADD_SIGNAL(MethodInfo("raise_request"));
242
ADD_SIGNAL(MethodInfo("delete_request"));
243
ADD_SIGNAL(MethodInfo("resize_request", PropertyInfo(Variant::VECTOR2, "new_size")));
244
ADD_SIGNAL(MethodInfo("resize_end", PropertyInfo(Variant::VECTOR2, "new_size")));
245
246
ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::VECTOR2, "from"), PropertyInfo(Variant::VECTOR2, "to")));
247
ADD_SIGNAL(MethodInfo("position_offset_changed"));
248
249
BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, GraphElement, resizer);
250
}
251
252