feat: modules moved and engine moved to submodule

This commit is contained in:
Jan van der Weide 2025-04-12 18:40:44 +02:00
parent dfb5e645cd
commit c33d2130cc
5136 changed files with 225275 additions and 64485 deletions

View file

@ -353,6 +353,62 @@ int GraphEdit::get_connection_count(const StringName &p_node, int p_port) {
return count;
}
GraphNode *GraphEdit::get_input_connection_target(const StringName &p_node, int p_port) {
for (const Ref<Connection> &conn : connections) {
if (conn->to_node == p_node && conn->to_port == p_port) {
GraphNode *from = Object::cast_to<GraphNode>(get_node(NodePath(conn->from_node)));
if (from) {
return from;
}
}
}
return nullptr;
}
GraphNode *GraphEdit::get_output_connection_target(const StringName &p_node, int p_port) {
for (const Ref<Connection> &conn : connections) {
if (conn->from_node == p_node && conn->from_port == p_port) {
GraphNode *to = Object::cast_to<GraphNode>(get_node(NodePath(conn->to_node)));
if (to) {
return to;
}
}
}
return nullptr;
}
String GraphEdit::get_connections_description(const StringName &p_node, int p_port) {
String out;
for (const Ref<Connection> &conn : connections) {
if (conn->from_node == p_node && conn->from_port == p_port) {
GraphNode *to = Object::cast_to<GraphNode>(get_node(NodePath(conn->to_node)));
if (to) {
if (!out.is_empty()) {
out += ", ";
}
String name = to->get_accessibility_name();
if (name.is_empty()) {
name = to->get_name();
}
out += vformat(ETR("connection to %s (%s) port %d"), name, to->get_title(), conn->to_port);
}
} else if (conn->to_node == p_node && conn->to_port == p_port) {
GraphNode *from = Object::cast_to<GraphNode>(get_node(NodePath(conn->from_node)));
if (from) {
if (!out.is_empty()) {
out += ", ";
}
String name = from->get_accessibility_name();
if (name.is_empty()) {
name = from->get_name();
}
out += vformat(ETR("connection from %s (%s) port %d"), name, from->get_title(), conn->from_port);
}
}
}
return out;
}
void GraphEdit::set_scroll_offset(const Vector2 &p_offset) {
setting_scroll_offset = true;
h_scrollbar->set_value(p_offset.x);
@ -780,6 +836,10 @@ void GraphEdit::_notification(int p_what) {
// Draw background fill.
draw_style_box(theme_cache.panel, Rect2(Point2(), get_size()));
if (has_focus()) {
draw_style_box(theme_cache.panel_focus, Rect2(Point2(), get_size()));
}
// Draw background grid.
if (show_grid) {
_draw_grid();
@ -958,9 +1018,172 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
return false;
}
void GraphEdit::start_keyboard_connecting(GraphNode *p_node, int p_in_port, int p_out_port) {
if (!p_node || p_in_port == p_out_port || (p_in_port != -1 && p_out_port != -1)) {
return;
}
connecting_valid = false;
keyboard_connecting = true;
if (p_in_port != -1) {
Vector2 pos = p_node->get_input_port_position(p_in_port) * zoom + p_node->get_position();
if (right_disconnects || valid_right_disconnect_types.has(p_node->get_input_port_type(p_in_port))) {
// Check disconnect.
for (const Ref<Connection> &conn : connection_map[p_node->get_name()]) {
if (conn->to_node == p_node->get_name() && conn->to_port == p_in_port) {
Node *fr = get_node(NodePath(conn->from_node));
if (Object::cast_to<GraphNode>(fr)) {
connecting_from_node = conn->from_node;
connecting_from_port_index = conn->from_port;
connecting_from_output = true;
connecting_type = Object::cast_to<GraphNode>(fr)->get_output_port_type(conn->from_port);
connecting_color = Object::cast_to<GraphNode>(fr)->get_output_port_color(conn->from_port);
connecting_target_valid = false;
connecting_to_point = pos;
just_disconnected = true;
if (connecting_type >= 0) {
emit_signal(SNAME("disconnection_request"), conn->from_node, conn->from_port, conn->to_node, conn->to_port);
fr = get_node(NodePath(connecting_from_node));
if (Object::cast_to<GraphNode>(fr)) {
connecting = true;
emit_signal(SNAME("connection_drag_started"), connecting_from_node, connecting_from_port_index, true);
}
}
return;
}
}
}
}
connecting_from_node = p_node->get_name();
connecting_from_port_index = p_in_port;
connecting_from_output = false;
connecting_type = p_node->get_input_port_type(p_in_port);
connecting_color = p_node->get_input_port_color(p_in_port);
connecting_target_valid = false;
connecting_to_point = pos;
if (connecting_type >= 0) {
connecting = true;
just_disconnected = false;
emit_signal(SNAME("connection_drag_started"), connecting_from_node, connecting_from_port_index, false);
}
return;
}
if (p_out_port != -1) {
Vector2 pos = p_node->get_output_port_position(p_out_port) * zoom + p_node->get_position();
if (valid_left_disconnect_types.has(p_node->get_output_port_type(p_out_port))) {
// Check disconnect.
for (const Ref<Connection> &conn : connection_map[p_node->get_name()]) {
if (conn->from_node == p_node->get_name() && conn->from_port == p_out_port) {
Node *to = get_node(NodePath(conn->to_node));
if (Object::cast_to<GraphNode>(to)) {
connecting_from_node = conn->to_node;
connecting_from_port_index = conn->to_port;
connecting_from_output = false;
connecting_type = Object::cast_to<GraphNode>(to)->get_input_port_type(conn->to_port);
connecting_color = Object::cast_to<GraphNode>(to)->get_input_port_color(conn->to_port);
connecting_target_valid = false;
connecting_to_point = pos;
if (connecting_type >= 0) {
just_disconnected = true;
emit_signal(SNAME("disconnection_request"), conn->from_node, conn->from_port, conn->to_node, conn->to_port);
to = get_node(NodePath(connecting_from_node)); // Maybe it was erased.
if (Object::cast_to<GraphNode>(to)) {
connecting = true;
emit_signal(SNAME("connection_drag_started"), connecting_from_node, connecting_from_port_index, false);
}
}
return;
}
}
}
}
connecting_from_node = p_node->get_name();
connecting_from_port_index = p_out_port;
connecting_from_output = true;
connecting_type = p_node->get_output_port_type(p_out_port);
connecting_color = p_node->get_output_port_color(p_out_port);
connecting_target_valid = false;
connecting_to_point = pos;
if (connecting_type >= 0) {
connecting = true;
just_disconnected = false;
emit_signal(SNAME("connection_drag_started"), connecting_from_node, connecting_from_port_index, true);
}
return;
}
}
void GraphEdit::end_keyboard_connecting(GraphNode *p_node, int p_in_port, int p_out_port) {
if (!p_node) {
return;
}
connecting_valid = true;
connecting_target_valid = false;
if (p_in_port != -1) {
Vector2 pos = p_node->get_input_port_position(p_in_port) * zoom + p_node->get_position();
int type = p_node->get_input_port_type(p_in_port);
if (type == connecting_type || p_node->is_ignoring_valid_connection_type() || valid_connection_types.has(ConnectionType(connecting_type, type))) {
connecting_target_valid = true;
connecting_to_point = pos;
connecting_target_node = p_node->get_name();
connecting_target_port_index = p_in_port;
}
}
if (p_out_port != -1) {
Vector2 pos = p_node->get_output_port_position(p_out_port) * zoom + p_node->get_position();
int type = p_node->get_output_port_type(p_out_port);
if (type == connecting_type || p_node->is_ignoring_valid_connection_type() || valid_connection_types.has(ConnectionType(type, connecting_type))) {
connecting_target_valid = true;
connecting_to_point = pos;
connecting_target_node = p_node->get_name();
connecting_target_port_index = p_out_port;
}
}
if (connecting_valid) {
if (connecting && connecting_target_valid) {
if (connecting_from_output) {
emit_signal(SNAME("connection_request"), connecting_from_node, connecting_from_port_index, connecting_target_node, connecting_target_port_index);
} else {
emit_signal(SNAME("connection_request"), connecting_target_node, connecting_target_port_index, connecting_from_node, connecting_from_port_index);
}
} else if (!just_disconnected) {
if (connecting_from_output) {
emit_signal(SNAME("connection_to_empty"), connecting_from_node, connecting_from_port_index, Vector2());
} else {
emit_signal(SNAME("connection_from_empty"), connecting_from_node, connecting_from_port_index, Vector2());
}
}
}
keyboard_connecting = false;
if (connecting) {
force_connection_drag_end();
}
}
Dictionary GraphEdit::get_type_names() const {
return type_names;
}
void GraphEdit::set_type_names(const Dictionary &p_names) {
type_names = p_names;
}
void GraphEdit::_top_connection_layer_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventMouseButton> mb = p_ev;
if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) {
if (keyboard_connecting) {
force_connection_drag_end();
keyboard_connecting = false;
}
connecting_valid = false;
click_pos = mb->get_position() / zoom;
for (int i = get_child_count() - 1; i >= 0; i--) {
@ -1086,7 +1309,7 @@ void GraphEdit::_top_connection_layer_input(const Ref<InputEvent> &p_ev) {
}
Ref<InputEventMouseMotion> mm = p_ev;
if (mm.is_valid() && connecting) {
if (mm.is_valid() && connecting && !keyboard_connecting) {
connecting_to_point = mm->get_position();
minimap->queue_redraw();
callable_mp(this, &GraphEdit::_update_top_connection_layer).call_deferred();
@ -1198,7 +1421,7 @@ bool GraphEdit::_check_clickable_control(Control *p_control, const Vector2 &mpos
control_rect.size *= zoom;
control_rect.position += p_offset;
if (!control_rect.has_point(mpos) || p_control->get_mouse_filter() == MOUSE_FILTER_IGNORE) {
if (!control_rect.has_point(mpos) || p_control->get_mouse_filter_with_recursive() == MOUSE_FILTER_IGNORE) {
// Test children.
for (int i = 0; i < p_control->get_child_count(); i++) {
Control *child_rect = Object::cast_to<Control>(p_control->get_child(i));
@ -1316,7 +1539,7 @@ Ref<GraphEdit::Connection> GraphEdit::get_closest_connection_at_point(const Vect
Vector<Vector2> points = get_connection_line(conn->_cache.from_pos * zoom, conn->_cache.to_pos * zoom);
for (int i = 0; i < points.size() - 1; i++) {
float distance = Geometry2D::get_distance_to_segment(transformed_point, &points[i]);
const real_t distance = Geometry2D::get_distance_to_segment(transformed_point, points[i], points[i + 1]);
if (distance <= lines_thickness * 0.5 + p_max_distance && distance < closest_distance) {
closest_connection = conn;
closest_distance = distance;
@ -1663,7 +1886,7 @@ void GraphEdit::_draw_grid() {
for (int i = from_pos.x; i < from_pos.x + len.x; i++) {
Color color;
if (ABS(i) % GRID_MINOR_STEPS_PER_MAJOR_LINE == 0) {
if (Math::abs(i) % GRID_MINOR_STEPS_PER_MAJOR_LINE == 0) {
color = theme_cache.grid_major;
} else {
color = theme_cache.grid_minor;
@ -1676,7 +1899,7 @@ void GraphEdit::_draw_grid() {
for (int i = from_pos.y; i < from_pos.y + len.y; i++) {
Color color;
if (ABS(i) % GRID_MINOR_STEPS_PER_MAJOR_LINE == 0) {
if (Math::abs(i) % GRID_MINOR_STEPS_PER_MAJOR_LINE == 0) {
color = theme_cache.grid_major;
} else {
color = theme_cache.grid_minor;
@ -1694,7 +1917,7 @@ void GraphEdit::_draw_grid() {
if (transparent_grid_minor.a != 0) {
for (int i = from_pos.x; i < from_pos.x + len.x; i++) {
for (int j = from_pos.y; j < from_pos.y + len.y; j++) {
if (ABS(i) % GRID_MINOR_STEPS_PER_MAJOR_DOT == 0 && ABS(j) % GRID_MINOR_STEPS_PER_MAJOR_DOT == 0) {
if (Math::abs(i) % GRID_MINOR_STEPS_PER_MAJOR_DOT == 0 && Math::abs(j) % GRID_MINOR_STEPS_PER_MAJOR_DOT == 0) {
continue;
}
@ -2142,6 +2365,7 @@ void GraphEdit::force_connection_drag_end() {
connecting = false;
connecting_valid = false;
keyboard_connecting = false;
minimap->queue_redraw();
queue_redraw();
connections_layer->queue_redraw();
@ -2329,6 +2553,24 @@ TypedArray<Dictionary> GraphEdit::_get_connections_intersecting_with_rect(const
return arr;
}
TypedArray<Dictionary> GraphEdit::_get_connection_list_from_node(const StringName &p_node) const {
ERR_FAIL_COND_V(!connection_map.has(p_node), TypedArray<Dictionary>());
List<Ref<GraphEdit::Connection>> connections_from_node = connection_map.get(p_node);
TypedArray<Dictionary> connections_from_node_dict;
for (const Ref<Connection> &conn : connections_from_node) {
Dictionary d;
d["from_node"] = conn->from_node;
d["from_port"] = conn->from_port;
d["to_node"] = conn->to_node;
d["to_port"] = conn->to_port;
d["keep_alive"] = conn->keep_alive;
connections_from_node_dict.push_back(d);
}
return connections_from_node_dict;
}
void GraphEdit::_zoom_minus() {
set_zoom(zoom / zoom_step);
}
@ -2689,6 +2931,7 @@ void GraphEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_connection_list"), &GraphEdit::_get_connection_list);
ClassDB::bind_method(D_METHOD("get_connection_count", "from_node", "from_port"), &GraphEdit::get_connection_count);
ClassDB::bind_method(D_METHOD("get_closest_connection_at_point", "point", "max_distance"), &GraphEdit::_get_closest_connection_at_point, DEFVAL(4.0));
ClassDB::bind_method(D_METHOD("get_connection_list_from_node", "node"), &GraphEdit::_get_connection_list_from_node);
ClassDB::bind_method(D_METHOD("get_connections_intersecting_with_rect", "rect"), &GraphEdit::_get_connections_intersecting_with_rect);
ClassDB::bind_method(D_METHOD("clear_connections"), &GraphEdit::clear_connections);
ClassDB::bind_method(D_METHOD("force_connection_drag_end"), &GraphEdit::force_connection_drag_end);
@ -2774,6 +3017,9 @@ void GraphEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_right_disconnects", "enable"), &GraphEdit::set_right_disconnects);
ClassDB::bind_method(D_METHOD("is_right_disconnects_enabled"), &GraphEdit::is_right_disconnects_enabled);
ClassDB::bind_method(D_METHOD("set_type_names", "type_names"), &GraphEdit::set_type_names);
ClassDB::bind_method(D_METHOD("get_type_names"), &GraphEdit::get_type_names);
GDVIRTUAL_BIND(_is_in_input_hotzone, "in_node", "in_port", "mouse_position");
GDVIRTUAL_BIND(_is_in_output_hotzone, "in_node", "in_port", "mouse_position");
@ -2794,6 +3040,8 @@ void GraphEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans"), "set_panning_scheme", "get_panning_scheme");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "right_disconnects"), "set_right_disconnects", "is_right_disconnects_enabled");
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "type_names", PROPERTY_HINT_DICTIONARY_TYPE, "int;String"), "set_type_names", "get_type_names");
ADD_GROUP("Connection Lines", "connection_lines");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "connection_lines_curvature"), "set_connection_lines_curvature", "get_connection_lines_curvature");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "connection_lines_thickness", PROPERTY_HINT_RANGE, "0,100,0.1,suffix:px"), "set_connection_lines_thickness", "get_connection_lines_thickness");
@ -2850,6 +3098,7 @@ void GraphEdit::_bind_methods() {
BIND_ENUM_CONSTANT(GRID_PATTERN_DOTS);
BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphEdit, panel);
BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphEdit, panel_focus);
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphEdit, grid_major);
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, GraphEdit, grid_minor);
@ -2958,7 +3207,8 @@ GraphEdit::GraphEdit() {
zoom_minus_button->set_theme_type_variation(SceneStringName(FlatButton));
zoom_minus_button->set_visible(show_zoom_buttons);
zoom_minus_button->set_tooltip_text(ETR("Zoom Out"));
zoom_minus_button->set_focus_mode(FOCUS_NONE);
zoom_minus_button->set_accessibility_name(ETR("Zoom Out"));
zoom_minus_button->set_focus_mode(FOCUS_ACCESSIBILITY);
menu_hbox->add_child(zoom_minus_button);
zoom_minus_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_zoom_minus));
@ -2966,7 +3216,8 @@ GraphEdit::GraphEdit() {
zoom_reset_button->set_theme_type_variation(SceneStringName(FlatButton));
zoom_reset_button->set_visible(show_zoom_buttons);
zoom_reset_button->set_tooltip_text(ETR("Zoom Reset"));
zoom_reset_button->set_focus_mode(FOCUS_NONE);
zoom_reset_button->set_accessibility_name(ETR("Zoom Reset"));
zoom_reset_button->set_focus_mode(FOCUS_ACCESSIBILITY);
menu_hbox->add_child(zoom_reset_button);
zoom_reset_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_zoom_reset));
@ -2974,7 +3225,8 @@ GraphEdit::GraphEdit() {
zoom_plus_button->set_theme_type_variation(SceneStringName(FlatButton));
zoom_plus_button->set_visible(show_zoom_buttons);
zoom_plus_button->set_tooltip_text(ETR("Zoom In"));
zoom_plus_button->set_focus_mode(FOCUS_NONE);
zoom_plus_button->set_accessibility_name(ETR("Zoom In"));
zoom_plus_button->set_focus_mode(FOCUS_ACCESSIBILITY);
menu_hbox->add_child(zoom_plus_button);
zoom_plus_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_zoom_plus));
@ -2986,6 +3238,7 @@ GraphEdit::GraphEdit() {
toggle_grid_button->set_toggle_mode(true);
toggle_grid_button->set_pressed(true);
toggle_grid_button->set_tooltip_text(ETR("Toggle the visual grid."));
toggle_grid_button->set_accessibility_name(ETR("Grid"));
toggle_grid_button->set_focus_mode(FOCUS_NONE);
menu_hbox->add_child(toggle_grid_button);
toggle_grid_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_show_grid_toggled));
@ -2995,6 +3248,7 @@ GraphEdit::GraphEdit() {
toggle_snapping_button->set_visible(show_grid_buttons);
toggle_snapping_button->set_toggle_mode(true);
toggle_snapping_button->set_tooltip_text(ETR("Toggle snapping to the grid."));
toggle_snapping_button->set_accessibility_name(ETR("Snap to Grid"));
toggle_snapping_button->set_pressed(snapping_enabled);
toggle_snapping_button->set_focus_mode(FOCUS_NONE);
menu_hbox->add_child(toggle_snapping_button);
@ -3007,6 +3261,7 @@ GraphEdit::GraphEdit() {
snapping_distance_spinbox->set_step(1);
snapping_distance_spinbox->set_value(snapping_distance);
snapping_distance_spinbox->set_tooltip_text(ETR("Change the snapping distance."));
snapping_distance_spinbox->set_accessibility_name(ETR("Snapping Distance"));
menu_hbox->add_child(snapping_distance_spinbox);
snapping_distance_spinbox->connect(SceneStringName(value_changed), callable_mp(this, &GraphEdit::_snapping_distance_changed));
@ -3017,6 +3272,7 @@ GraphEdit::GraphEdit() {
minimap_button->set_visible(show_minimap_button);
minimap_button->set_toggle_mode(true);
minimap_button->set_tooltip_text(ETR("Toggle the graph minimap."));
minimap_button->set_accessibility_name(ETR("Minimap"));
minimap_button->set_pressed(show_grid);
minimap_button->set_focus_mode(FOCUS_NONE);
menu_hbox->add_child(minimap_button);
@ -3025,6 +3281,7 @@ GraphEdit::GraphEdit() {
arrange_button = memnew(Button);
arrange_button->set_theme_type_variation(SceneStringName(FlatButton));
arrange_button->set_visible(show_arrange_button);
arrange_button->set_accessibility_name(ETR("Auto Arrange"));
arrange_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::arrange_nodes));
arrange_button->set_focus_mode(FOCUS_NONE);
menu_hbox->add_child(arrange_button);