generated from mstar/godot-template
91 lines
2.2 KiB
GDScript
91 lines
2.2 KiB
GDScript
@tool
|
|
extends Container
|
|
# Custom style normal, focus, arrow
|
|
|
|
var selected: = false:
|
|
set = set_selected
|
|
|
|
|
|
func _init():
|
|
|
|
focus_mode = FOCUS_CLICK
|
|
mouse_filter = MOUSE_FILTER_IGNORE
|
|
|
|
func _draw():
|
|
pivot_at_line_start()
|
|
var from = Vector2.ZERO
|
|
from.y += size.y / 2.0
|
|
var to = size
|
|
to.y -= size.y / 2.0
|
|
var arrow = get_theme_icon("arrow", "FlowChartLine")
|
|
var tint = Color.WHITE
|
|
if selected:
|
|
tint = get_theme_stylebox("focus", "FlowChartLine").shadow_color
|
|
draw_style_box(get_theme_stylebox("focus", "FlowChartLine"), Rect2(Vector2.ZERO, size))
|
|
else:
|
|
draw_style_box(get_theme_stylebox("normal", "FlowChartLine"), Rect2(Vector2.ZERO, size))
|
|
|
|
|
|
draw_texture(arrow, Vector2.ZERO - arrow.get_size() / 2 + size / 2, tint)
|
|
|
|
func _get_minimum_size():
|
|
return Vector2(0, 5)
|
|
|
|
func pivot_at_line_start():
|
|
pivot_offset.x = 0
|
|
pivot_offset.y = size.y / 2.0
|
|
|
|
func join(from, to, offset=Vector2.ZERO, clip_rects=[]):
|
|
# Offset along perpendicular direction
|
|
var perp_dir = from.direction_to(to).rotated(deg_to_rad(90.0)).normalized()
|
|
from -= perp_dir * offset
|
|
to -= perp_dir * offset
|
|
|
|
var dist = from.distance_to(to)
|
|
var dir = from.direction_to(to)
|
|
var center = from + dir * dist / 2
|
|
|
|
# Clip line with provided Rect2 array
|
|
var clipped = [[from, to]]
|
|
var line_from = from
|
|
var line_to = to
|
|
for clip_rect in clip_rects:
|
|
if clipped.size() == 0:
|
|
break
|
|
|
|
line_from = clipped[0][0]
|
|
line_to = clipped[0][1]
|
|
clipped = Geometry2D.clip_polyline_with_polygon(
|
|
[line_from, line_to],
|
|
[clip_rect.position, Vector2(clip_rect.position.x, clip_rect.end.y),
|
|
clip_rect.end, Vector2(clip_rect.end.x, clip_rect.position.y)]
|
|
)
|
|
|
|
if clipped.size() > 0:
|
|
from = clipped[0][0]
|
|
to = clipped[0][1]
|
|
else: # Line is totally overlapped
|
|
from = center
|
|
to = center + dir * 0.1
|
|
|
|
# Extends line by 2px to minimise ugly seam
|
|
from -= dir * 2.0
|
|
to += dir * 2.0
|
|
|
|
size.x = to.distance_to(from)
|
|
# size.y equals to the thickness of line
|
|
position = from
|
|
position.y -= size.y / 2.0
|
|
rotation = Vector2.RIGHT.angle_to(dir)
|
|
pivot_at_line_start()
|
|
|
|
func set_selected(v):
|
|
if selected != v:
|
|
selected = v
|
|
queue_redraw()
|
|
|
|
func get_from_pos():
|
|
return get_transform() * (position)
|
|
|
|
func get_to_pos():
|
|
return get_transform() * (position + size)
|