Expose connection hot zones in GraphNode
This commit is contained in:
parent
61d681cfb9
commit
0449b30bbc
|
@ -18,6 +18,43 @@
|
|||
Virtual method which can be overridden to customize how connections are drawn.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_is_in_input_hotzone" qualifiers="virtual">
|
||||
<return type="bool" />
|
||||
<argument index="0" name="graph_node" type="Object" />
|
||||
<argument index="1" name="slot_index" type="int" />
|
||||
<argument index="2" name="mouse_position" type="Vector2" />
|
||||
<description>
|
||||
Returns whether the [code]mouse_position[/code] is in the input hot zone.
|
||||
By default, a hot zone is a [Rect2] positioned such that its center is at [code]graph_node[/code].[method GraphNode.get_connection_input_position]([code]slot_index[/code]) (For output's case, call [method GraphNode.get_connection_output_position] instead). The hot zone's width is twice the Theme Property [code]port_grab_distance_horizontal[/code], and its height is twice the [code]port_grab_distance_vertical[/code].
|
||||
Below is a sample code to help get started:
|
||||
[codeblock]
|
||||
func _is_in_input_hotzone(graph_node, slot_index, mouse_position):
|
||||
var slot_size : Vector2 = Vector2(get_theme_constant("port_grab_distance_horizontal"), get_theme_constant("port_grab_distance_vertical"))
|
||||
var slot_pos : Vector2 = graph_node.get_position() + graph_node.get_connection_input_position(slot_index) - slot_size / 2
|
||||
var rect = Rect2(slot_pos, slot_size)
|
||||
|
||||
return rect.has_point(mouse_position)
|
||||
[/codeblock]
|
||||
</description>
|
||||
</method>
|
||||
<method name="_is_in_output_hotzone" qualifiers="virtual">
|
||||
<return type="bool" />
|
||||
<argument index="0" name="graph_node" type="Object" />
|
||||
<argument index="1" name="slot_index" type="int" />
|
||||
<argument index="2" name="mouse_position" type="Vector2" />
|
||||
<description>
|
||||
Returns whether the [code]mouse_position[/code] is in the output hot zone. For more information on hot zones, see [method _is_in_input_hotzone].
|
||||
Below is a sample code to help get started:
|
||||
[codeblock]
|
||||
func _is_in_output_hotzone(graph_node, slot_index, mouse_position):
|
||||
var slot_size : Vector2 = Vector2(get_theme_constant("port_grab_distance_horizontal"), get_theme_constant("port_grab_distance_vertical"))
|
||||
var slot_pos : Vector2 = graph_node.get_position() + graph_node.get_connection_output_position(slot_index) - slot_size / 2
|
||||
var rect = Rect2(slot_pos, slot_size)
|
||||
|
||||
return rect.has_point(mouse_position)
|
||||
[/codeblock]
|
||||
</description>
|
||||
</method>
|
||||
<method name="add_valid_connection_type">
|
||||
<return type="void" />
|
||||
<argument index="0" name="from_type" type="int" />
|
||||
|
|
|
@ -524,15 +524,13 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
|
|||
}
|
||||
|
||||
for (int j = 0; j < gn->get_connection_output_count(); j++) {
|
||||
Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
|
||||
if (is_in_hot_zone(pos / zoom, p_point / zoom, port_size, false)) {
|
||||
if (is_in_output_hotzone(gn, j, p_point / zoom, port_size)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < gn->get_connection_input_count(); j++) {
|
||||
Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
|
||||
if (is_in_hot_zone(pos / zoom, p_point / zoom, port_size, true)) {
|
||||
if (is_in_input_hotzone(gn, j, p_point / zoom, port_size)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -557,7 +555,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
|
|||
|
||||
for (int j = 0; j < gn->get_connection_output_count(); j++) {
|
||||
Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
|
||||
if (is_in_hot_zone(pos / zoom, click_pos, port_size, false)) {
|
||||
if (is_in_output_hotzone(gn, j, click_pos, port_size)) {
|
||||
if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) {
|
||||
//check disconnect
|
||||
for (const Connection &E : connections) {
|
||||
|
@ -599,7 +597,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
|
|||
|
||||
for (int j = 0; j < gn->get_connection_input_count(); j++) {
|
||||
Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
|
||||
if (is_in_hot_zone(pos / zoom, click_pos, port_size, true)) {
|
||||
if (is_in_input_hotzone(gn, j, click_pos, port_size)) {
|
||||
if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) {
|
||||
//check disconnect
|
||||
for (const Connection &E : connections) {
|
||||
|
@ -665,7 +663,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
|
|||
for (int j = 0; j < gn->get_connection_output_count(); j++) {
|
||||
Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
|
||||
int type = gn->get_connection_output_type(j);
|
||||
if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos / zoom, mpos, port_size, false)) {
|
||||
if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_output_hotzone(gn, j, mpos, port_size)) {
|
||||
connecting_target = true;
|
||||
connecting_to = pos;
|
||||
connecting_target_to = gn->get_name();
|
||||
|
@ -677,7 +675,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
|
|||
for (int j = 0; j < gn->get_connection_input_count(); j++) {
|
||||
Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
|
||||
int type = gn->get_connection_input_type(j);
|
||||
if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos / zoom, mpos, port_size, true)) {
|
||||
if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_input_hotzone(gn, j, mpos, port_size)) {
|
||||
connecting_target = true;
|
||||
connecting_to = pos;
|
||||
connecting_target_to = gn->get_name();
|
||||
|
@ -748,25 +746,27 @@ bool GraphEdit::_check_clickable_control(Control *p_control, const Vector2 &pos)
|
|||
}
|
||||
}
|
||||
|
||||
bool GraphEdit::is_in_hot_zone(const Vector2 &pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left) {
|
||||
if (p_left) {
|
||||
if (!Rect2(
|
||||
pos.x - p_port_size.x / 2 - port_grab_distance_horizontal,
|
||||
pos.y - p_port_size.y / 2 - port_grab_distance_vertical / 2,
|
||||
p_port_size.x + port_grab_distance_horizontal,
|
||||
p_port_size.y + port_grab_distance_vertical)
|
||||
.has_point(p_mouse_pos)) {
|
||||
return false;
|
||||
}
|
||||
bool GraphEdit::is_in_input_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) {
|
||||
if (get_script_instance() && get_script_instance()->has_method("_is_in_input_hotzone")) {
|
||||
return get_script_instance()->call("_is_in_input_hotzone", p_graph_node, p_slot_index, p_mouse_pos);
|
||||
} else {
|
||||
if (!Rect2(
|
||||
pos.x - p_port_size.x / 2,
|
||||
pos.y - p_port_size.y / 2 - port_grab_distance_vertical / 2,
|
||||
p_port_size.x + port_grab_distance_horizontal,
|
||||
p_port_size.y + port_grab_distance_vertical)
|
||||
.has_point(p_mouse_pos)) {
|
||||
return false;
|
||||
}
|
||||
Vector2 pos = p_graph_node->get_connection_input_position(p_slot_index) + p_graph_node->get_position();
|
||||
return is_in_port_hotzone(pos / zoom, p_mouse_pos, p_port_size, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool GraphEdit::is_in_output_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size) {
|
||||
if (get_script_instance() && get_script_instance()->has_method("_is_in_output_hotzone")) {
|
||||
return get_script_instance()->call("_is_in_output_hotzone", p_graph_node, p_slot_index, p_mouse_pos);
|
||||
} else {
|
||||
Vector2 pos = p_graph_node->get_connection_output_position(p_slot_index) + p_graph_node->get_position();
|
||||
return is_in_port_hotzone(pos / zoom, p_mouse_pos, p_port_size, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool GraphEdit::is_in_port_hotzone(const Vector2 &pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left) {
|
||||
if (!Rect2(pos.x - port_grab_distance_horizontal, pos.y - port_grab_distance_vertical, port_grab_distance_horizontal * 2, port_grab_distance_vertical * 2).has_point(p_mouse_pos)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
|
@ -2188,6 +2188,8 @@ void GraphEdit::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("is_right_disconnects_enabled"), &GraphEdit::is_right_disconnects_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_update_scroll_offset"), &GraphEdit::_update_scroll_offset);
|
||||
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "_is_in_input_hotzone", PropertyInfo(Variant::OBJECT, "graph_node"), PropertyInfo(Variant::INT, "slot_index"), PropertyInfo(Variant::VECTOR2, "mouse_position")));
|
||||
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "_is_in_output_hotzone", PropertyInfo(Variant::OBJECT, "graph_node"), PropertyInfo(Variant::INT, "slot_index"), PropertyInfo(Variant::VECTOR2, "mouse_position")));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_zoom_hbox"), &GraphEdit::get_zoom_hbox);
|
||||
|
||||
|
|
|
@ -183,7 +183,9 @@ private:
|
|||
GraphEditMinimap *minimap;
|
||||
void _top_layer_input(const Ref<InputEvent> &p_ev);
|
||||
|
||||
bool is_in_hot_zone(const Vector2 &pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left);
|
||||
bool is_in_input_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size);
|
||||
bool is_in_output_hotzone(GraphNode *p_graph_node, int p_slot_index, const Vector2 &p_mouse_pos, const Vector2i &p_port_size);
|
||||
bool is_in_port_hotzone(const Vector2 &pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left);
|
||||
|
||||
void _top_layer_draw();
|
||||
void _connections_layer_draw();
|
||||
|
|
Loading…
Reference in New Issue