GraphEdit
继承: Control < CanvasItem < Node < Object
图结构编辑器,使用 GraphNode。
描述
GraphEdit 提供了用于对各种图进行创建、操作、显示的工具。它在引擎中的主要目的是驱动可视化编程系统,例如可视化着色器,但也可以在用户项目中使用。
GraphEdit 本身只是一个空容器,表示一个可以放置 GraphNode 的无限栅格。每个 GraphNode 代表图中的一个节点,是连接方案中的单个数据单元。而 GraphEdit 则有助于控制节点和节点之间的各种交互。当用户尝试连接、断开或删除一个 GraphNode 时,GraphEdit 中会发出对应的信号,但默认情况下不执行任何动作。使用此控件的程序员负责实现必要的逻辑,来确定应如何处理每个请求。
性能:强烈建议在使用 GraphEdit 时启用低处理器使用模式(见 OS.low_processor_usage_mode)。
注意:请注意,由于技术限制,Node.get_children() 还将返回名为 _connection_layer 的连接层节点。该行为可能会在未来版本中发生变化。
属性
clip_contents |
|
|
|
||
|
||
|
||
|
||
focus_mode |
|
|
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
方法
_get_connection_line(from_position: Vector2, to_position: Vector2) virtual const |
|
_is_in_input_hotzone(in_node: Object, in_port: int, mouse_position: Vector2) virtual |
|
_is_in_output_hotzone(in_node: Object, in_port: int, mouse_position: Vector2) virtual |
|
_is_node_hover_valid(from_node: StringName, from_port: int, to_node: StringName, to_port: int) virtual |
|
void |
add_valid_connection_type(from_type: int, to_type: int) |
void |
|
void |
|
void |
|
void |
attach_graph_element_to_frame(element: StringName, frame: StringName) |
void |
|
connect_node(from_node: StringName, from_port: int, to_node: StringName, to_port: int, keep_alive: bool = false) |
|
void |
detach_graph_element_from_frame(element: StringName) |
void |
disconnect_node(from_node: StringName, from_port: int, to_node: StringName, to_port: int) |
void |
|
get_closest_connection_at_point(point: Vector2, max_distance: float = 4.0) const |
|
get_connection_count(from_node: StringName, from_port: int) |
|
get_connection_line(from_node: Vector2, to_node: Vector2) const |
|
get_connection_list_from_node(node: StringName) const |
|
get_connections_intersecting_with_rect(rect: Rect2) const |
|
get_element_frame(element: StringName) |
|
is_node_connected(from_node: StringName, from_port: int, to_node: StringName, to_port: int) |
|
is_valid_connection_type(from_type: int, to_type: int) const |
|
void |
remove_valid_connection_type(from_type: int, to_type: int) |
void |
|
void |
|
void |
set_connection_activity(from_node: StringName, from_port: int, to_node: StringName, to_port: int, amount: float) |
void |
set_selected(node: Node) |
主题属性
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
信号
begin_node_move() 🔗
在 GraphElement 移动开始时发出。
connection_drag_ended() 🔗
在连接拖动结束时发出。
connection_drag_started(from_node: StringName, from_port: int, is_output: bool) 🔗
在连接拖动开始时发出。
connection_from_empty(to_node: StringName, to_port: int, release_position: Vector2) 🔗
当用户将连接从输入端口拖动到图形的空白区域时发出。
connection_request(from_node: StringName, from_port: int, to_node: StringName, to_port: int) 🔗
当尝试创建 from_node GraphNode 的 from_port 和 to_node GraphNode 的 to_port 之间的连接时发出。
connection_to_empty(from_node: StringName, from_port: int, release_position: Vector2) 🔗
当用户将连接从输出端口拖动到图形的空白区域时发出。
copy_nodes_request() 🔗
当该 GraphEdit 捕获 ui_copy 动作(默认情况下为 Ctrl + C)时发出。一般来说,该信号指示所选的 GraphElement 应被复制。
cut_nodes_request() 🔗
当该 GraphEdit 捕获 ui_cut 动作(默认情况下为 Ctrl + X)时发出。一般来说,该信号指示所选的 GraphElement 应被剪切。
delete_nodes_request(nodes: Array[StringName]) 🔗
当该 GraphEdit 捕获 ui_graph_delete 动作(默认为 Delete)时触发。
nodes 是应被移除的节点的名称的数组。这些通常包括所有选定的节点。
disconnection_request(from_node: StringName, from_port: int, to_node: StringName, to_port: int) 🔗
当试图移除 from_node GraphNode 的 from_port 和 to_node GraphNode 的 to_port 之间的连接时发出。
duplicate_nodes_request() 🔗
当该 GraphEdit 捕获 ui_graph_duplicate 动作(默认为 Ctrl + D)时触发。一般来说,该信号指示应被复制的所选的 GraphElement。
end_node_move() 🔗
在 GraphElement 移动结束时发出。
frame_rect_changed(frame: GraphFrame, new_rect: Rect2) 🔗
当 GraphFrame frame 大小调整为 new_rect 时发出。
graph_elements_linked_to_frame_request(elements: Array, frame: StringName) 🔗
当一个或多个 GraphElement 被放到名为 frame 的 GraphFrame 上,且它们之前未被附加到任何其他框中时发出。
elements 是要附加的 GraphElement 数组。
当给定的 GraphElement 节点被取消选择时发出。
当给定的 GraphElement 节点被选中时发出。
paste_nodes_request() 🔗
当该 GraphEdit 捕获 ui_paste 动作(默认为 Ctrl + V)时触发。一般来说,该信号指示应被粘贴的先前复制的 GraphElement。
popup_request(at_position: Vector2) 🔗
当请求弹出窗口时发出。在 GraphEdit 中右键点击时发生。at_position为该信号被发出时鼠标指针的位置。
scroll_offset_changed(offset: Vector2) 🔗
当用户改变滚动偏移量时发出。在代码中改变滚动偏移量时,它不会被触发。
枚举
enum PanningScheme: 🔗
PanningScheme SCROLL_ZOOMS = 0
鼠标滚轮进行缩放,Ctrl + 鼠标滚轮进行视图的移动。
PanningScheme SCROLL_PANS = 1
鼠标滚轮进行视图的移动,Ctrl + 鼠标滚轮进行缩放。
enum GridPattern: 🔗
GridPattern GRID_PATTERN_LINES = 0
使用实线绘制网格。
GridPattern GRID_PATTERN_DOTS = 1
使用点线绘制网格。
属性说明
bool connection_lines_antialiased = true 🔗
如果为 true,节点之间的线将使用抗锯齿。
float connection_lines_curvature = 0.5 🔗
节点之间连线的曲率。0 得到的是直线。
float connection_lines_thickness = 4.0 🔗
节点之间连线的粗细。
Array[Dictionary] connections = [] 🔗
void set_connections(value: Array[Dictionary])
Array[Dictionary] get_connection_list()
GraphNode 之间的连接。
连接由 Dictionary 代表,形式为:
{
from_node: StringName,
from_port: int,
to_node: StringName,
to_port: int,
keep_alive: bool
}
重绘时,如果 keep_alive 为 false 的连接无效,则可能会被自动删除。
GridPattern grid_pattern = 0 🔗
void set_grid_pattern(value: GridPattern)
GridPattern get_grid_pattern()
绘制网格时使用的图案。
如果为 true,小图是可见的。
float minimap_opacity = 0.65 🔗
小图矩形的不透明度。
Vector2 minimap_size = Vector2(240, 160) 🔗
小图矩形的大小。地图自身基于网格区域的大小,并被缩放以适应这个矩形。
PanningScheme panning_scheme = 0 🔗
void set_panning_scheme(value: PanningScheme)
PanningScheme get_panning_scheme()
定义使用鼠标滚轮平移的控制方案。
bool right_disconnects = false 🔗
如果为 true,通过拖动右端,可以断开 GraphEdit 中现有的连接。
Vector2 scroll_offset = Vector2(0, 0) 🔗
滚动偏移量。
bool show_arrange_button = true 🔗
如果为 true,则自动排列图形节点的按钮可见。
如果为 true,则该网格可见。
bool show_grid_buttons = true 🔗
如果为 true,则允许配置栅格和吸附选项的按钮可见。
如果为 true,则菜单栏可见。
bool show_minimap_button = true 🔗
如果为 true,则切换小地图的按钮可见。
bool show_zoom_buttons = true 🔗
如果为 true,则允许更改和重置缩放级别的按钮可见。
bool show_zoom_label = false 🔗
如果为 true,则使带有当前缩放级别的标签可见。缩放级别以百分比显示。
吸附距离,单位为像素,也决定了栅格线距离。
bool snapping_enabled = true 🔗
如果为 true,启用自动吸附。
Dictionary type_names = {} 🔗
void set_type_names(value: Dictionary)
Dictionary get_type_names()
Dictionary of human-readable port type names.
当前缩放值。
缩放上限。
缩放下限。
每个缩放级别的步长。
方法说明
PackedVector2Array _get_connection_line(from_position: Vector2, to_position: Vector2) virtual const 🔗
可以重写的虚方法,以自定义如何绘制连接。
bool _is_in_input_hotzone(in_node: Object, in_port: int, mouse_position: Vector2) virtual 🔗
返回 mouse_position 是否在输入热区。
默认情况下,热区是一个 Rect2,其中心位于 in_node.GraphNode.get_input_port_position()(in_port)(对于输出的情况,请改为调用 GraphNode.get_output_port_position())。热区的宽度是主题属性 port_grab_distance_horizontal 的两倍,高度是 port_grab_distance_vertical 的两倍。
下面是一个示例代码,以帮助入门:
func _is_in_input_hotzone(in_node, in_port, mouse_position):
var port_size = Vector2(get_theme_constant("port_grab_distance_horizontal"), get_theme_constant("port_grab_distance_vertical"))
var port_pos = in_node.get_position() + in_node.get_input_port_position(in_port) - port_size / 2
var rect = Rect2(port_pos, port_size)
return rect.has_point(mouse_position)
bool _is_in_output_hotzone(in_node: Object, in_port: int, mouse_position: Vector2) virtual 🔗
返回 mouse_position 是否在输出热区。有关热区的更多信息,请参阅 _is_in_input_hotzone()。
下面是一个示例代码,以帮助入门:
func _is_in_output_hotzone(in_node, in_port, mouse_position):
var port_size = Vector2(get_theme_constant("port_grab_distance_horizontal"), get_theme_constant("port_grab_distance_vertical"))
var port_pos = in_node.get_position() + in_node.get_output_port_position(in_port) - port_size / 2
var rect = Rect2(port_pos, port_size)
return rect.has_point(mouse_position)
bool _is_node_hover_valid(from_node: StringName, from_port: int, to_node: StringName, to_port: int) virtual 🔗
当用户在有效端口上拖动连接时,该虚拟方法可用于插入额外的错误检测。
如果连接确实有效,则返回 true;如果连接不可能,则返回 false。如果连接是不可能的,则不会捕捉到该端口,因此不会发起对该端口的连接请求。
在该示例中,抑制了与同一节点的连接:
func _is_node_hover_valid(from, from_port, to, to_port):
return from != to
public override bool _IsNodeHoverValid(StringName fromNode, int fromPort, StringName toNode, int toPort)
{
return fromNode != toNode;
}
void add_valid_connection_type(from_type: int, to_type: int) 🔗
允许两种不同端口类型之间的连接。端口类型是使用 GraphNode.set_slot() 方法为每个插槽的左右端口单独定义的。
另见 is_valid_connection_type() 和 remove_valid_connection_type()。
void add_valid_left_disconnect_type(type: int) 🔗
如果 GraphNode 插槽的左侧端口具有指定的类型,则允许在从该端口拖动时断开节点。另见 remove_valid_left_disconnect_type()。
void add_valid_right_disconnect_type(type: int) 🔗
如果 GraphNode 插槽的右侧端口具有指定的类型,则允许在从该端口拖动时断开节点。另见 remove_valid_right_disconnect_type()。
void arrange_nodes() 🔗
重新排列布局中的选定节点,使连接之间的交叉最少,节点之间的水平和垂直间隙保持一致。
void attach_graph_element_to_frame(element: StringName, frame: StringName) 🔗
将 element GraphElement 附加到 frame GraphFrame。
void clear_connections() 🔗
移除节点之间的所有连接。
Error connect_node(from_node: StringName, from_port: int, to_node: StringName, to_port: int, keep_alive: bool = false) 🔗
在来源 GraphNode 节点 from_node 的 from_port 端口和目标 GraphNode 节点 to_node 的 to_port 端口之间创建连接。如果已存在连接,则不会创建连接。
keep_alive 为 false 的连接如果在重绘期间失效,则可能会被自动删除。
void detach_graph_element_from_frame(element: StringName) 🔗
将 element GraphElement 从其当前附加的 GraphFrame 中分离出来。
void disconnect_node(from_node: StringName, from_port: int, to_node: StringName, to_port: int) 🔗
移除 from_node GraphNode 的 from_port 和 to_node GraphNode 的 to_port 之间的连接。如果该连接不存在,则不移除任何连接。
void force_connection_drag_end() 🔗
结束当前连接的创建。换句话说,如果正在拖动一个连接,可以使用该方法中止该过程,并移除鼠标光标后面的线。
这最好与 connection_drag_started 和 connection_drag_ended 一起使用,以添加自定义的行为,如通过快捷方式添加节点。
注意:该方法会抑制除 connection_drag_ended 之外的任何其他连接请求信号。
Array[StringName] get_attached_nodes_of_frame(frame: StringName) 🔗
返回附加到给定名称的 GraphFrame 的节点名称数组。
Dictionary get_closest_connection_at_point(point: Vector2, max_distance: float = 4.0) const 🔗
返回到屏幕空间中给定点的最近连接。如果在 max_distance 像素内未找到连接,则返回空的 Dictionary。
连接由以下形式的结构组成:
{
from_node: StringName,
from_port: int,
to_node: StringName,
to_port: int,
keep_alive: bool
}
例如,可以像这样实现获取在给定鼠标位置处的连接:
var connection = get_closest_connection_at_point(mouse_event.get_position())
int get_connection_count(from_node: StringName, from_port: int) 🔗
返回 from_node 节点的 from_port 端口的连接数量。
PackedVector2Array get_connection_line(from_node: Vector2, to_node: Vector2) const 🔗
返回构成 from_node 和 to_node 之间的连接的点。
Array[Dictionary] get_connection_list_from_node(node: StringName) const 🔗
返回包含 node 节点所有连接的 Array。
连接使用 Dictionary 表示,形式为:
{
from_node: StringName,
from_port: int,
to_node: StringName,
to_port: int,
keep_alive: bool
}
示例:获取指定端口的所有连接:
func get_connection_list_from_port(node, port):
var connections = get_connection_list_from_node(node)
var result = []
for connection in connections:
var dict = {}
if connection["from_node"] == node and connection["from_port"] == port:
dict["node"] = connection["to_node"]
dict["port"] = connection["to_port"]
dict["type"] = "left"
result.push_back(dict)
elif connection["to_node"] == node and connection["to_port"] == port:
dict["node"] = connection["from_node"]
dict["port"] = connection["from_port"]
dict["type"] = "right"
result.push_back(dict)
return result
Array[Dictionary] get_connections_intersecting_with_rect(rect: Rect2) const 🔗
返回一个 Array,其中包含与给定 Rect2 相交的连接列表。
连接由 Dictionary 表示,结构如下:
{
from_node: StringName,
from_port: int,
to_node: StringName,
to_port: int,
keep_alive: bool
}
GraphFrame get_element_frame(element: StringName) 🔗
返回包含给定名称的 GraphElement 的 GraphFrame。
获取包含图形左上角的缩放和网格捕捉控件的 HBoxContainer。你可以使用此方法重新定位工具栏或向其添加自定义控件。
警告:这是一个必需的内部节点,删除和释放它可能会导致崩溃。如果你希望隐藏它或其任何子项,请使用它们的 CanvasItem.visible 属性。
bool is_node_connected(from_node: StringName, from_port: int, to_node: StringName, to_port: int) 🔗
如果 from_node GraphNode 的 from_port 连接到 to_node GraphNode 的 to_port,则返回 true。
bool is_valid_connection_type(from_type: int, to_type: int) const 🔗
返回是否可以在两种不同的端口类型之间建立连接。端口类型是使用 GraphNode.set_slot() 方法为每个插槽的左右端口单独定义的。
另见 add_valid_connection_type() 和 remove_valid_connection_type()。
void remove_valid_connection_type(from_type: int, to_type: int) 🔗
不允许先前由 add_valid_connection_type() 允许的两种不同端口类型之间的连接。端口类型是通过 GraphNode.set_slot() 方法为每个插槽的左右端口单独定义的。
另见 is_valid_connection_type()。
void remove_valid_left_disconnect_type(type: int) 🔗
Disallows to disconnect nodes when dragging from the left port of the GraphNode's slot if it has the specified type. Use this to disable a disconnection previously allowed with add_valid_left_disconnect_type().
void remove_valid_right_disconnect_type(type: int) 🔗
Disallows to disconnect nodes when dragging from the right port of the GraphNode's slot if it has the specified type. Use this to disable a disconnection previously allowed with add_valid_right_disconnect_type().
void set_connection_activity(from_node: StringName, from_port: int, to_node: StringName, to_port: int, amount: float) 🔗
使用 activity 主题属性中提供的颜色,设置 from_node 的 from_port 和 to_node 的 to_port 之间的连接的颜色。使用 amount 作为权重,在连接颜色和活动颜色之间线性插值颜色。
void set_selected(node: Node) 🔗
将指定的 node 节点设置为选中的节点。
主题属性说明
Color activity = Color(1, 1, 1, 1) 🔗
根据连接的活动值插入连接线的颜色(请参阅 set_connection_activity())。
Color connection_hover_tint_color = Color(0, 0, 0, 0.3) 🔗
当鼠标悬停在连接线上时与该连接线混合的颜色。
Color connection_rim_color = Color(0.1, 0.1, 0.1, 0.6) 🔗
每条连接线周围的边缘颜色,用于使相交线更容易区分。
Color connection_valid_target_tint_color = Color(1, 1, 1, 0.4) 🔗
当前拖动的连接悬停在有效目标端口上时与该连接线混合的颜色。
Color grid_major = Color(1, 1, 1, 0.2) 🔗
主要栅格线/点的颜色。
Color grid_minor = Color(1, 1, 1, 0.05) 🔗
次要栅格线/点的颜色。
Color selection_fill = Color(1, 1, 1, 0.3) 🔗
选定的矩形的填充颜色。
Color selection_stroke = Color(1, 1, 1, 0.8) 🔗
选择的矩形的轮廓颜色。
int connection_hover_thickness = 0 🔗
Widens the line of a connection when the mouse is hovering over it by a percentage factor. A value of 0 disables the highlight. A value of 100 doubles the line width.
int port_hotzone_inner_extent = 22 🔗
能够抓取端口的(内侧)横向范围。
int port_hotzone_outer_extent = 26 🔗
能够抓取端口的(外侧)横向范围。
网格开关按钮的图标。
用于自动排列图形的布局按钮的图标。
小地图开关按钮的图标。
吸附开关按钮的图标。
放大按钮的图标。
缩小按钮的图标。
缩放重置按钮的图标。
There is currently no description for this theme property. Please help us by contributing one!
绘制在栅格下方的背景。
当 GraphEdit 处于聚焦状态时使用的 StyleBox(使用辅助应用时)。