]> Untitled Git - wolf-seeking-sheep.git/blob - addons/dialogic/Editor/TimelineEditor/VisualEditor/TimelineArea.gd
Initial Godot project with Dialogic 2.0-Alpha-17
[wolf-seeking-sheep.git] / addons / dialogic / Editor / TimelineEditor / VisualEditor / TimelineArea.gd
1 @tool
2 extends ScrollContainer
3
4 # Script of the TimelineArea (that contains the event blocks).
5 # Manages the drawing of the event lines and event dragging.
6
7
8 enum DragTypes {NOTHING, NEW_EVENT, EXISTING_EVENTS}
9
10 var drag_type: DragTypes = DragTypes.NOTHING
11 var drag_data: Variant
12 var drag_to_position := 0:
13         set(value):
14                 drag_to_position = value
15                 drag_to_position_updated = true
16 var dragging := false
17 var drag_to_position_updated := false
18
19
20 signal drag_completed(type, index, data)
21 signal drag_canceled()
22
23
24 func _ready() -> void:
25         resized.connect(add_extra_scroll_area_to_timeline)
26         %Timeline.child_entered_tree.connect(add_extra_scroll_area_to_timeline)
27
28         # This prevents the view to turn black if you are editing this scene in Godot
29         if find_parent('EditorView'):
30                 %TimelineArea.get_theme_color("background_color", "CodeEdit")
31
32
33 #region EVENT DRAGGING
34 ################################################################################
35
36 func start_dragging(type:DragTypes, data:Variant) -> void:
37         dragging = true
38         drag_type = type
39         drag_data = data
40         drag_to_position_updated = false
41
42
43 func _input(event:InputEvent) -> void:
44         if !dragging:
45                 return
46         if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
47                 if !event.is_pressed():
48                         finish_dragging()
49
50
51 func _process(delta:float) -> void:
52         if !dragging:
53                 return
54
55         for child in %Timeline.get_children():
56                 if (child.global_position.y < get_global_mouse_position().y) and \
57                         (child.global_position.y+child.size.y > get_global_mouse_position().y):
58
59                         if get_global_mouse_position().y > child.global_position.y+(child.size.y/2.0):
60                                 drag_to_position = child.get_index()+1
61                                 queue_redraw()
62                         else:
63                                 drag_to_position = child.get_index()
64                                 queue_redraw()
65
66
67 func finish_dragging() -> void:
68         dragging = false
69         if drag_to_position_updated and get_global_rect().has_point(get_global_mouse_position()):
70                 drag_completed.emit(drag_type, drag_to_position, drag_data)
71         else:
72                 drag_canceled.emit()
73         queue_redraw()
74
75 #endregion
76
77
78 #region LINE DRAWING
79 ################################################################################
80
81 func _draw() -> void:
82         var line_width := 5 * DialogicUtil.get_editor_scale()
83         var horizontal_line_length := 100 * DialogicUtil.get_editor_scale()
84         var color_multiplier := Color(1,1,1,0.25)
85         var selected_color_multiplier := Color(1,1,1,1)
86
87
88         ## Draw Event Lines
89         for idx in range($Timeline.get_child_count()):
90                 var block: Control = $Timeline.get_child(idx)
91
92                 if not "resource" in block:
93                         continue
94
95                 if not block.visible:
96                         continue
97
98                 if block.resource is DialogicEndBranchEvent:
99                         continue
100
101                 if not (block.has_any_enabled_body_content or block.resource.can_contain_events):
102                         continue
103
104                 var icon_panel_height: int = block.get_node('%IconPanel').size.y
105                 var rect_position: Vector2 = block.get_node('%IconPanel').global_position+Vector2(0,1)*block.get_node('%IconPanel').size+Vector2(0,-4)
106                 var color: Color = block.resource.event_color
107
108                 if block.is_selected() or block.end_node and block.end_node.is_selected():
109                         color *= selected_color_multiplier
110                 else:
111                         color *= color_multiplier
112
113                 if block.expanded and not block.resource.can_contain_events:
114                         draw_rect(Rect2(rect_position-global_position+Vector2(line_width, 0), Vector2(line_width, block.size.y-block.get_node('%IconPanel').size.y)), color)
115
116                 ## If the indentation has not changed, nothing else happens
117                 if idx >= $Timeline.get_child_count()-1 or block.current_indent_level >= $Timeline.get_child(idx+1).current_indent_level:
118                         continue
119
120                 ## Draw connection between opening and end branch events
121                 if block.resource.can_contain_events:
122                         var end_node: Node = block.end_node
123
124                         if end_node != null:
125                                 var v_length: float = end_node.global_position.y+end_node.size.y/2-rect_position.y
126                                 #var rect_size := Vector2(line_width, )
127                                 var offset := Vector2(line_width, 0)
128
129                                 # Draw vertical line
130                                 draw_rect(Rect2(rect_position-global_position+offset, Vector2(line_width, v_length)), color)
131                                 # Draw horizonal line (on END BRANCH event)
132                                 draw_rect(Rect2(
133                                                         rect_position.x+line_width-global_position.x+offset.x,
134                                                         rect_position.y+v_length-line_width-global_position.y,
135                                                         horizontal_line_length-offset.x,
136                                                         line_width),
137                                                         color)
138
139                 if block.resource.wants_to_group:
140                         var group_color: Color = block.resource.event_color*color_multiplier
141                         var group_starter := true
142                         if idx != 0:
143                                 var block_above := $Timeline.get_child(idx-1)
144                                 if block_above.resource.event_name == block.resource.event_name:
145                                         group_starter = false
146                                 if block_above.resource is DialogicEndBranchEvent and block_above.parent_node.resource.event_name == block.resource.event_name:
147                                         group_starter = false
148
149                         ## Draw small horizontal line on any event in group
150                         draw_rect(Rect2(
151                                         rect_position.x-global_position.x-line_width,
152                                         rect_position.y-global_position.y-icon_panel_height/2,
153                                         line_width,
154                                         line_width),
155                                         group_color)
156
157                         if group_starter:
158                                 ## Find the last event in the group (or that events END BRANCH)
159                                 var sub_idx := idx
160                                 var group_end_idx := idx
161                                 while sub_idx < $Timeline.get_child_count()-1:
162                                         sub_idx += 1
163                                         if $Timeline.get_child(sub_idx).current_indent_level == block.current_indent_level-1:
164                                                 group_end_idx = sub_idx-1
165                                                 break
166
167                                 var end_node := $Timeline.get_child(group_end_idx)
168
169                                 var offset := Vector2(-2*line_width, -icon_panel_height/2)
170                                 var v_length: float = end_node.global_position.y - rect_position.y + icon_panel_height
171
172                                 ## Draw vertical line
173                                 draw_rect(Rect2(
174                                                         rect_position.x - global_position.x + offset.x,
175                                                         rect_position.y - global_position.y + offset.y,
176                                                         line_width,
177                                                         v_length),
178                                                         group_color)
179
180
181         ## Draw line that indicates the dragging position
182         if dragging and get_global_rect().has_point(get_global_mouse_position()):
183                 var height: int = 0
184                 if drag_to_position == %Timeline.get_child_count():
185                         height = %Timeline.get_child(-1).global_position.y+%Timeline.get_child(-1).size.y-global_position.y-(line_width/2.0)
186                 else:
187                         height = %Timeline.get_child(drag_to_position).global_position.y-global_position.y-(line_width/2.0)
188
189                 draw_line(Vector2(0, height), Vector2(size.x*0.9, height), get_theme_color("accent_color", "Editor"), line_width*.3)
190
191 #endregion
192
193
194 #region SPACE BELOW
195 ################################################################################
196
197 func add_extra_scroll_area_to_timeline(fake_arg:Variant=null) -> void:
198         if %Timeline.get_children().size() > 4:
199                 %Timeline.custom_minimum_size.y = 0
200                 %Timeline.size.y = 0
201                 if %Timeline.size.y + 200 > %TimelineArea.size.y:
202                         %Timeline.custom_minimum_size = Vector2(0, %Timeline.size.y + 200)
203
204 #endregion