You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
6.4 KiB
200 lines
6.4 KiB
@tool
|
|
extends ScrollContainer
|
|
|
|
# Script of the TimelineArea (that contains the event blocks).
|
|
# Manages the drawing of the event lines and event dragging.
|
|
|
|
|
|
enum DragTypes {NOTHING, NEW_EVENT, EXISTING_EVENTS}
|
|
|
|
var drag_type : DragTypes = DragTypes.NOTHING
|
|
var drag_data : Variant
|
|
var drag_to_position := 0
|
|
var dragging := false
|
|
|
|
|
|
signal drag_completed(type, index, data)
|
|
signal drag_canceled()
|
|
|
|
|
|
func _ready() -> void:
|
|
resized.connect(add_extra_scroll_area_to_timeline)
|
|
%Timeline.child_entered_tree.connect(add_extra_scroll_area_to_timeline)
|
|
|
|
# This prevents the view to turn black if you are editing this scene in Godot
|
|
if find_parent('EditorView'):
|
|
%TimelineArea.get_theme_color("background_color", "CodeEdit")
|
|
|
|
|
|
#region EVENT DRAGGING
|
|
################################################################################
|
|
|
|
func start_dragging(type:DragTypes, data:Variant) -> void:
|
|
dragging = true
|
|
drag_type = type
|
|
drag_data = data
|
|
|
|
|
|
func _input(event:InputEvent) -> void:
|
|
if !dragging:
|
|
return
|
|
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
|
|
if !event.is_pressed():
|
|
finish_dragging()
|
|
|
|
|
|
func _process(delta:float) -> void:
|
|
if !dragging:
|
|
return
|
|
|
|
for child in %Timeline.get_children():
|
|
if (child.global_position.y < get_global_mouse_position().y) and \
|
|
(child.global_position.y+child.size.y > get_global_mouse_position().y):
|
|
|
|
if get_global_mouse_position().y > child.global_position.y+(child.size.y/2.0):
|
|
drag_to_position = child.get_index()+1
|
|
queue_redraw()
|
|
else:
|
|
drag_to_position = child.get_index()
|
|
queue_redraw()
|
|
|
|
|
|
func finish_dragging():
|
|
dragging = false
|
|
if get_global_rect().has_point(get_global_mouse_position()):
|
|
drag_completed.emit(drag_type, drag_to_position, drag_data)
|
|
else:
|
|
drag_canceled.emit()
|
|
queue_redraw()
|
|
|
|
#endregion
|
|
|
|
|
|
#region LINE DRAWING
|
|
################################################################################
|
|
|
|
func _draw() -> void:
|
|
var line_width := 5 * DialogicUtil.get_editor_scale()
|
|
var horizontal_line_length := 100 * DialogicUtil.get_editor_scale()
|
|
var color_multiplier := Color(1,1,1,0.25)
|
|
var selected_color_multiplier := Color(1,1,1,1)
|
|
|
|
|
|
## Draw Event Lines
|
|
for idx in range($Timeline.get_child_count()):
|
|
var block : Control = $Timeline.get_child(idx)
|
|
|
|
if not "resource" in block:
|
|
continue
|
|
|
|
if not block.visible:
|
|
continue
|
|
|
|
if block.resource is DialogicEndBranchEvent:
|
|
continue
|
|
|
|
if not (block.has_any_enabled_body_content or block.resource.can_contain_events):
|
|
continue
|
|
|
|
var icon_panel_height: int = block.get_node('%IconPanel').size.y
|
|
var rect_position: Vector2 = block.get_node('%IconPanel').global_position+Vector2(0,1)*block.get_node('%IconPanel').size+Vector2(0,-4)
|
|
var color: Color = block.resource.event_color
|
|
|
|
if block.is_selected() or block.end_node and block.end_node.is_selected():
|
|
color *= selected_color_multiplier
|
|
else:
|
|
color *= color_multiplier
|
|
|
|
if block.expanded and not block.resource.can_contain_events:
|
|
draw_rect(Rect2(rect_position-global_position+Vector2(line_width, 0), Vector2(line_width, block.size.y-block.get_node('%IconPanel').size.y)), color)
|
|
|
|
## If the indentation has not changed, nothing else happens
|
|
if idx >= $Timeline.get_child_count()-1 or block.current_indent_level >= $Timeline.get_child(idx+1).current_indent_level:
|
|
continue
|
|
|
|
## Draw connection between opening and end branch events
|
|
if block.resource.can_contain_events:
|
|
var end_node: Node = block.end_node
|
|
|
|
if end_node != null:
|
|
var v_length: float = end_node.global_position.y+end_node.size.y/2-rect_position.y
|
|
#var rect_size := Vector2(line_width, )
|
|
var offset := Vector2(line_width, 0)
|
|
|
|
# Draw vertical line
|
|
draw_rect(Rect2(rect_position-global_position+offset, Vector2(line_width, v_length)), color)
|
|
# Draw horizonal line (on END BRANCH event)
|
|
draw_rect(Rect2(
|
|
rect_position.x+line_width-global_position.x+offset.x,
|
|
rect_position.y+v_length-line_width-global_position.y,
|
|
horizontal_line_length-offset.x,
|
|
line_width),
|
|
color)
|
|
|
|
if block.resource.wants_to_group:
|
|
var group_color: Color = block.resource.event_color*color_multiplier
|
|
var group_starter := true
|
|
if idx != 0:
|
|
var block_above := $Timeline.get_child(idx-1)
|
|
if block_above.resource.event_name == block.resource.event_name:
|
|
group_starter = false
|
|
if block_above.resource is DialogicEndBranchEvent and block_above.parent_node.resource.event_name == block.resource.event_name:
|
|
group_starter = false
|
|
|
|
## Draw small horizontal line on any event in group
|
|
draw_rect(Rect2(
|
|
rect_position.x-global_position.x-line_width,
|
|
rect_position.y-global_position.y-icon_panel_height/2,
|
|
line_width,
|
|
line_width),
|
|
group_color)
|
|
|
|
if group_starter:
|
|
## Find the last event in the group (or that events END BRANCH)
|
|
var sub_idx := idx
|
|
var group_end_idx := idx
|
|
while sub_idx < $Timeline.get_child_count()-1:
|
|
sub_idx += 1
|
|
if $Timeline.get_child(sub_idx).current_indent_level == block.current_indent_level-1:
|
|
group_end_idx = sub_idx-1
|
|
break
|
|
|
|
var end_node := $Timeline.get_child(group_end_idx)
|
|
|
|
var offset := Vector2(-2*line_width, -icon_panel_height/2)
|
|
var v_length: float = end_node.global_position.y - rect_position.y + icon_panel_height
|
|
|
|
## Draw vertical line
|
|
draw_rect(Rect2(
|
|
rect_position.x - global_position.x + offset.x,
|
|
rect_position.y - global_position.y + offset.y,
|
|
line_width,
|
|
v_length),
|
|
group_color)
|
|
|
|
|
|
## Draw line that indicates the dragging position
|
|
if dragging and get_global_rect().has_point(get_global_mouse_position()):
|
|
var height: int = 0
|
|
if drag_to_position == %Timeline.get_child_count():
|
|
height = %Timeline.get_child(-1).global_position.y+%Timeline.get_child(-1).size.y-global_position.y-(line_width/2.0)
|
|
else:
|
|
height = %Timeline.get_child(drag_to_position).global_position.y-global_position.y-(line_width/2.0)
|
|
|
|
draw_line(Vector2(0, height), Vector2(size.x*0.9, height), get_theme_color("accent_color", "Editor"), line_width*.3)
|
|
|
|
#endregion
|
|
|
|
|
|
#region SPACE BELOW
|
|
################################################################################
|
|
|
|
func add_extra_scroll_area_to_timeline(fake_arg:Variant=null) -> void:
|
|
if %Timeline.get_children().size() > 4:
|
|
%Timeline.custom_minimum_size.y = 0
|
|
%Timeline.size.y = 0
|
|
if %Timeline.size.y + 200 > %TimelineArea.size.y:
|
|
%Timeline.custom_minimum_size = Vector2(0, %Timeline.size.y + 200)
|
|
|
|
#endregion
|