feat(stage): complete phase 20b action plans
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
class_name StageActionSummaryGlyph
|
||||
extends Control
|
||||
## Small, screen-sized glyphs for the Stage action-plan summary rows.
|
||||
|
||||
var _kind: String = "move"
|
||||
var _tint: Color = Color("#8BD9FF")
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
focus_mode = Control.FOCUS_NONE
|
||||
|
||||
|
||||
func configure(kind: String, tint: Color) -> void:
|
||||
_kind = kind
|
||||
_tint = tint
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
draw_in_canvas(self, _kind, Vector2.ZERO, 1.0, _tint)
|
||||
|
||||
|
||||
## Draws the same vector glyph into another CanvasItem's active draw callback.
|
||||
## `origin` is the top-left of the 28 x 30 glyph design space.
|
||||
static func draw_in_canvas(canvas: CanvasItem, kind: String, origin: Vector2, scale_factor: float, tint: Color) -> void:
|
||||
if canvas == null or scale_factor <= 0.0:
|
||||
return
|
||||
match kind:
|
||||
"move":
|
||||
_draw_move(canvas, origin, scale_factor, tint)
|
||||
"speak":
|
||||
_draw_speech(canvas, origin, scale_factor, tint)
|
||||
"wait":
|
||||
_draw_wait(canvas, origin, scale_factor, tint)
|
||||
"ragdoll":
|
||||
_draw_ragdoll(canvas, origin, scale_factor, tint)
|
||||
"recover":
|
||||
_draw_recover(canvas, origin, scale_factor, tint)
|
||||
"drop_prop":
|
||||
_draw_drop_prop(canvas, origin, scale_factor, tint)
|
||||
"throw_prop":
|
||||
_draw_throw_prop(canvas, origin, scale_factor, tint)
|
||||
"set_down_prop":
|
||||
_draw_set_down_prop(canvas, origin, scale_factor, tint)
|
||||
"use_prop":
|
||||
_draw_use_prop(canvas, origin, scale_factor, tint)
|
||||
|
||||
|
||||
static func _draw_move(canvas: CanvasItem, origin: Vector2, scale_factor: float, tint: Color) -> void:
|
||||
var route := PackedVector2Array([
|
||||
origin + Vector2(4.0, 24.0) * scale_factor,
|
||||
origin + Vector2(8.0, 15.0) * scale_factor,
|
||||
origin + Vector2(13.0, 19.0) * scale_factor,
|
||||
origin + Vector2(24.0, 7.0) * scale_factor,
|
||||
])
|
||||
canvas.draw_polyline(route, tint, 2.8 * scale_factor, true)
|
||||
canvas.draw_circle(origin + Vector2(4.0, 24.0) * scale_factor, 2.5 * scale_factor, tint, true, -1.0, true)
|
||||
var arrow_head := PackedVector2Array([
|
||||
origin + Vector2(17.0, 7.0) * scale_factor,
|
||||
origin + Vector2(25.0, 6.0) * scale_factor,
|
||||
origin + Vector2(24.0, 14.0) * scale_factor,
|
||||
])
|
||||
canvas.draw_polyline(arrow_head, tint, 2.8 * scale_factor, true)
|
||||
|
||||
|
||||
static func _draw_speech(canvas: CanvasItem, origin: Vector2, scale_factor: float, tint: Color) -> void:
|
||||
var outline := PackedVector2Array([
|
||||
origin + Vector2(5.0, 5.0) * scale_factor,
|
||||
origin + Vector2(22.0, 5.0) * scale_factor,
|
||||
origin + Vector2(26.0, 9.0) * scale_factor,
|
||||
origin + Vector2(26.0, 18.0) * scale_factor,
|
||||
origin + Vector2(22.0, 22.0) * scale_factor,
|
||||
origin + Vector2(15.0, 22.0) * scale_factor,
|
||||
origin + Vector2(8.0, 28.0) * scale_factor,
|
||||
origin + Vector2(8.0, 22.0) * scale_factor,
|
||||
origin + Vector2(5.0, 22.0) * scale_factor,
|
||||
origin + Vector2(2.0, 19.0) * scale_factor,
|
||||
origin + Vector2(2.0, 8.0) * scale_factor,
|
||||
origin + Vector2(5.0, 5.0) * scale_factor,
|
||||
])
|
||||
canvas.draw_polyline(outline, tint, 2.2 * scale_factor, true)
|
||||
|
||||
|
||||
static func _draw_wait(canvas: CanvasItem, origin: Vector2, scale_factor: float, tint: Color) -> void:
|
||||
var outline := PackedVector2Array([
|
||||
origin + Vector2(6.0, 5.0) * scale_factor,
|
||||
origin + Vector2(24.0, 5.0) * scale_factor,
|
||||
origin + Vector2(22.0, 9.0) * scale_factor,
|
||||
origin + Vector2(17.0, 14.0) * scale_factor,
|
||||
origin + Vector2(22.0, 19.0) * scale_factor,
|
||||
origin + Vector2(24.0, 23.0) * scale_factor,
|
||||
origin + Vector2(6.0, 23.0) * scale_factor,
|
||||
origin + Vector2(8.0, 19.0) * scale_factor,
|
||||
origin + Vector2(13.0, 14.0) * scale_factor,
|
||||
origin + Vector2(8.0, 9.0) * scale_factor,
|
||||
origin + Vector2(6.0, 5.0) * scale_factor,
|
||||
])
|
||||
canvas.draw_polyline(outline, tint, 2.2 * scale_factor, true)
|
||||
canvas.draw_line(origin + Vector2(9.0, 8.0) * scale_factor, origin + Vector2(21.0, 8.0) * scale_factor, tint, 2.0 * scale_factor, true)
|
||||
canvas.draw_line(origin + Vector2(9.0, 20.0) * scale_factor, origin + Vector2(21.0, 20.0) * scale_factor, tint, 2.0 * scale_factor, true)
|
||||
|
||||
|
||||
static func _draw_ragdoll(canvas: CanvasItem, origin: Vector2, scale_factor: float, tint: Color) -> void:
|
||||
var center: Vector2 = origin + Vector2(14.0, 15.0) * scale_factor
|
||||
var points := PackedVector2Array([
|
||||
center + Vector2(0.0, -13.0) * scale_factor,
|
||||
center + Vector2(3.0, -5.0) * scale_factor,
|
||||
center + Vector2(10.0, -10.0) * scale_factor,
|
||||
center + Vector2(7.0, -2.0) * scale_factor,
|
||||
center + Vector2(14.0, 1.0) * scale_factor,
|
||||
center + Vector2(6.0, 4.0) * scale_factor,
|
||||
center + Vector2(10.0, 11.0) * scale_factor,
|
||||
center + Vector2(2.0, 7.0) * scale_factor,
|
||||
center + Vector2(-2.0, 14.0) * scale_factor,
|
||||
center + Vector2(-5.0, 6.0) * scale_factor,
|
||||
center + Vector2(-12.0, 10.0) * scale_factor,
|
||||
center + Vector2(-8.0, 2.0) * scale_factor,
|
||||
center + Vector2(-14.0, -2.0) * scale_factor,
|
||||
center + Vector2(-6.0, -5.0) * scale_factor,
|
||||
center + Vector2(-10.0, -12.0) * scale_factor,
|
||||
center + Vector2(-2.0, -7.0) * scale_factor,
|
||||
])
|
||||
canvas.draw_colored_polygon(points, tint)
|
||||
|
||||
|
||||
static func _draw_recover(canvas: CanvasItem, origin: Vector2, scale_factor: float, tint: Color) -> void:
|
||||
var center: Vector2 = origin + Vector2(14.0, 15.0) * scale_factor
|
||||
var arc := PackedVector2Array()
|
||||
for index: int in 16:
|
||||
var angle: float = deg_to_rad(-55.0 + float(index) / 15.0 * 285.0)
|
||||
arc.append(center + Vector2(cos(angle), sin(angle)) * 10.0 * scale_factor)
|
||||
canvas.draw_polyline(arc, tint, 2.4 * scale_factor, true)
|
||||
var end_angle: float = deg_to_rad(230.0)
|
||||
var tip: Vector2 = center + Vector2(cos(end_angle), sin(end_angle)) * 10.0 * scale_factor
|
||||
var tangent: Vector2 = Vector2(-sin(end_angle), cos(end_angle))
|
||||
var base: Vector2 = tip - tangent * 7.0 * scale_factor
|
||||
var wing: Vector2 = Vector2(-tangent.y, tangent.x) * 4.0 * scale_factor
|
||||
canvas.draw_colored_polygon(PackedVector2Array([
|
||||
tip,
|
||||
base + wing,
|
||||
base - wing,
|
||||
]), tint)
|
||||
|
||||
|
||||
static func _draw_drop_prop(canvas: CanvasItem, origin: Vector2, scale_factor: float, tint: Color) -> void:
|
||||
canvas.draw_rect(Rect2(origin + Vector2(4.0, 3.0) * scale_factor, Vector2(20.0, 9.0) * scale_factor), tint, false, 2.2 * scale_factor, true)
|
||||
canvas.draw_line(origin + Vector2(14.0, 13.0) * scale_factor, origin + Vector2(14.0, 23.0) * scale_factor, tint, 2.5 * scale_factor, true)
|
||||
canvas.draw_line(origin + Vector2(14.0, 23.0) * scale_factor, origin + Vector2(8.0, 18.0) * scale_factor, tint, 2.5 * scale_factor, true)
|
||||
canvas.draw_line(origin + Vector2(14.0, 23.0) * scale_factor, origin + Vector2(20.0, 18.0) * scale_factor, tint, 2.5 * scale_factor, true)
|
||||
canvas.draw_line(origin + Vector2(4.0, 28.0) * scale_factor, origin + Vector2(24.0, 28.0) * scale_factor, tint, 2.0 * scale_factor, true)
|
||||
|
||||
|
||||
static func _draw_throw_prop(canvas: CanvasItem, origin: Vector2, scale_factor: float, tint: Color) -> void:
|
||||
var bow := PackedVector2Array([
|
||||
origin + Vector2(17.0, 3.0) * scale_factor,
|
||||
origin + Vector2(11.0, 5.0) * scale_factor,
|
||||
origin + Vector2(6.0, 9.0) * scale_factor,
|
||||
origin + Vector2(4.0, 15.0) * scale_factor,
|
||||
origin + Vector2(6.0, 21.0) * scale_factor,
|
||||
origin + Vector2(11.0, 25.0) * scale_factor,
|
||||
origin + Vector2(17.0, 27.0) * scale_factor,
|
||||
])
|
||||
canvas.draw_polyline(bow, tint, 2.4 * scale_factor, true)
|
||||
canvas.draw_line(origin + Vector2(17.0, 3.0) * scale_factor, origin + Vector2(17.0, 27.0) * scale_factor, tint, 1.6 * scale_factor, true)
|
||||
canvas.draw_line(origin + Vector2(2.0, 15.0) * scale_factor, origin + Vector2(26.0, 15.0) * scale_factor, tint, 2.6 * scale_factor, true)
|
||||
canvas.draw_polyline(PackedVector2Array([
|
||||
origin + Vector2(20.0, 9.0) * scale_factor,
|
||||
origin + Vector2(27.0, 15.0) * scale_factor,
|
||||
origin + Vector2(20.0, 21.0) * scale_factor,
|
||||
]), tint, 2.6 * scale_factor, true)
|
||||
|
||||
|
||||
static func _draw_set_down_prop(canvas: CanvasItem, origin: Vector2, scale_factor: float, tint: Color) -> void:
|
||||
canvas.draw_line(origin + Vector2(14.0, 3.0) * scale_factor, origin + Vector2(14.0, 12.0) * scale_factor, tint, 2.4 * scale_factor, true)
|
||||
canvas.draw_polyline(PackedVector2Array([
|
||||
origin + Vector2(9.0, 8.0) * scale_factor,
|
||||
origin + Vector2(14.0, 13.0) * scale_factor,
|
||||
origin + Vector2(19.0, 8.0) * scale_factor,
|
||||
]), tint, 2.4 * scale_factor, true)
|
||||
canvas.draw_rect(Rect2(origin + Vector2(6.0, 14.0) * scale_factor, Vector2(16.0, 10.0) * scale_factor), tint, false, 2.2 * scale_factor, true)
|
||||
canvas.draw_line(origin + Vector2(3.0, 27.0) * scale_factor, origin + Vector2(25.0, 27.0) * scale_factor, tint, 2.0 * scale_factor, true)
|
||||
|
||||
|
||||
static func _draw_use_prop(canvas: CanvasItem, origin: Vector2, scale_factor: float, tint: Color) -> void:
|
||||
canvas.draw_rect(Rect2(origin + Vector2(3.0, 12.0) * scale_factor, Vector2(16.0, 13.0) * scale_factor), tint, false, 2.2 * scale_factor, true)
|
||||
var spark := PackedVector2Array([
|
||||
origin + Vector2(22.0, 3.0) * scale_factor,
|
||||
origin + Vector2(24.0, 9.0) * scale_factor,
|
||||
origin + Vector2(28.0, 11.0) * scale_factor,
|
||||
origin + Vector2(23.0, 13.0) * scale_factor,
|
||||
origin + Vector2(21.0, 18.0) * scale_factor,
|
||||
origin + Vector2(19.0, 13.0) * scale_factor,
|
||||
origin + Vector2(15.0, 11.0) * scale_factor,
|
||||
origin + Vector2(20.0, 9.0) * scale_factor,
|
||||
origin + Vector2(22.0, 3.0) * scale_factor,
|
||||
])
|
||||
canvas.draw_polyline(spark, tint, 2.0 * scale_factor, true)
|
||||
@@ -0,0 +1 @@
|
||||
uid://jv06t4nihqrb
|
||||
@@ -18,6 +18,7 @@ var _rename_button: Button
|
||||
var _close_button: Button
|
||||
var _scroll: ScrollContainer
|
||||
var _body: VBoxContainer
|
||||
var _pinned: VBoxContainer
|
||||
var _collapsible: bool = false
|
||||
var _collapsed: bool = false
|
||||
var _close_visible: bool = true
|
||||
@@ -167,6 +168,10 @@ func body() -> VBoxContainer:
|
||||
return _body
|
||||
|
||||
|
||||
func pinned_content() -> VBoxContainer:
|
||||
return _pinned
|
||||
|
||||
|
||||
func set_safe_rect(rect: Rect2) -> void:
|
||||
_safe_rect = rect
|
||||
request_fit()
|
||||
@@ -184,6 +189,22 @@ func reset_scroll() -> void:
|
||||
_scroll.scroll_vertical = 0
|
||||
|
||||
|
||||
func get_body_scroll_vertical() -> int:
|
||||
return _scroll.scroll_vertical if _scroll != null else 0
|
||||
|
||||
|
||||
func set_body_scroll_vertical(value: int) -> void:
|
||||
if _scroll != null:
|
||||
_scroll.scroll_vertical = maxi(0, value)
|
||||
|
||||
|
||||
func scroll_to_control(control: Control) -> void:
|
||||
if _scroll == null or control == null or not is_instance_valid(control):
|
||||
return
|
||||
var content_y: float = control.global_position.y - _scroll.get_global_rect().position.y + _scroll.scroll_vertical
|
||||
_scroll.scroll_vertical = maxi(0, int(roundf(content_y)))
|
||||
|
||||
|
||||
func focus_first_control() -> void:
|
||||
if _body == null:
|
||||
return
|
||||
@@ -274,10 +295,10 @@ func _build_shell() -> void:
|
||||
_header.add_child(_icon)
|
||||
_title = Label.new()
|
||||
_title.name = "InspectorTitle"
|
||||
_title.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
_title.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
_title.max_lines_visible = 2
|
||||
_title.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
|
||||
_title.size_flags_horizontal = Control.SIZE_EXPAND_FILL | Control.SIZE_SHRINK_END
|
||||
_title.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
_title.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
_header.add_child(_title)
|
||||
@@ -303,6 +324,10 @@ func _build_shell() -> void:
|
||||
_close_button.focus_mode = Control.FOCUS_ALL
|
||||
_close_button.pressed.connect(_on_close_button_pressed)
|
||||
_header.add_child(_close_button)
|
||||
_pinned = VBoxContainer.new()
|
||||
_pinned.name = "InspectorPinnedContent"
|
||||
_pinned.add_theme_constant_override("separation", 8)
|
||||
_layout.add_child(_pinned)
|
||||
|
||||
_scroll = ScrollContainer.new()
|
||||
_scroll.name = "InspectorBodyScroll"
|
||||
@@ -326,7 +351,8 @@ func _fit_to_content() -> void:
|
||||
rect = get_viewport_rect()
|
||||
var inset := float(_integer("stage_panels.shell.edge_inset", 12, 0, 48))
|
||||
var preferred_width := float(_integer("stage_panels.shell.preferred_width", 380, 220, 720))
|
||||
var card_width := minf(preferred_width, maxf(1.0, rect.size.x - inset * 2.0))
|
||||
var max_width := float(_integer("stage_panels.shell.max_width", 380, 220, 720))
|
||||
var card_width := minf(minf(preferred_width, max_width), maxf(1.0, rect.size.x - inset * 2.0))
|
||||
custom_minimum_size.x = card_width
|
||||
size.x = card_width
|
||||
await get_tree().process_frame
|
||||
@@ -338,7 +364,9 @@ func _fit_to_content() -> void:
|
||||
rect = _safe_rect
|
||||
if rect.size.x <= 0.0 or rect.size.y <= 0.0:
|
||||
rect = get_viewport_rect()
|
||||
card_width = minf(preferred_width, maxf(1.0, rect.size.x - inset * 2.0))
|
||||
preferred_width = float(_integer("stage_panels.shell.preferred_width", 380, 220, 720))
|
||||
max_width = float(_integer("stage_panels.shell.max_width", 380, 220, 720))
|
||||
card_width = minf(minf(preferred_width, max_width), maxf(1.0, rect.size.x - inset * 2.0))
|
||||
custom_minimum_size.x = card_width
|
||||
size.x = card_width
|
||||
var padding := float(_integer("stage_panels.shell.padding", 12, 4, 28))
|
||||
@@ -346,7 +374,9 @@ func _fit_to_content() -> void:
|
||||
var header_height := maxf(44.0, _header.get_combined_minimum_size().y)
|
||||
var body_height := _body.get_combined_minimum_size().y
|
||||
var show_body: bool = not _collapsed and _body_visible
|
||||
var fixed_height := header_height + (gap if show_body else 0.0) + padding * 2.0
|
||||
var pinned_visible: bool = _pinned.visible and _pinned.get_child_count() > 0
|
||||
var pinned_height: float = _pinned.get_combined_minimum_size().y if pinned_visible else 0.0
|
||||
var fixed_height := header_height + (gap if pinned_visible else 0.0) + pinned_height + (gap if show_body else 0.0) + padding * 2.0
|
||||
var available_height := maxf(72.0, rect.size.y - inset * 2.0)
|
||||
var natural_height := fixed_height + (body_height if show_body else 0.0)
|
||||
var card_height := minf(natural_height, available_height)
|
||||
@@ -355,8 +385,12 @@ func _fit_to_content() -> void:
|
||||
# previous full-content minimum can clamp the new height until another layout.
|
||||
_scroll.custom_minimum_size.y = scroll_height
|
||||
_scroll.update_minimum_size()
|
||||
position = Vector2(rect.position.x + rect.size.x - inset - card_width, rect.position.y + inset)
|
||||
size = Vector2(card_width, card_height)
|
||||
# Containers can raise the actual width to fit their children. Anchor from that
|
||||
# final width so a content minimum cannot consume the right-edge gutter.
|
||||
var left_limit := rect.position.x + inset
|
||||
var right_limit := rect.position.x + rect.size.x - inset - size.x
|
||||
position = Vector2(clampf(right_limit, left_limit, maxf(left_limit, right_limit)), rect.position.y + inset)
|
||||
_fit_pending = false
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user