You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-14 13:41:12 +00:00
Base accessibility API.
This commit is contained in:
@@ -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();
|
||||
@@ -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();
|
||||
@@ -2793,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");
|
||||
|
||||
@@ -2813,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");
|
||||
@@ -2869,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);
|
||||
|
||||
@@ -2977,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));
|
||||
|
||||
@@ -2985,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));
|
||||
|
||||
@@ -2993,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));
|
||||
|
||||
@@ -3005,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));
|
||||
@@ -3014,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);
|
||||
@@ -3026,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));
|
||||
|
||||
@@ -3036,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);
|
||||
@@ -3044,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);
|
||||
|
||||
Reference in New Issue
Block a user