Add animated organizer tabs
This commit is contained in:
parent
39f3bfcfea
commit
78b91c350b
5 changed files with 285 additions and 21 deletions
188
ui/components/organizer_tab.gd
Normal file
188
ui/components/organizer_tab.gd
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
class_name OrganizerTab
|
||||
extends Button
|
||||
|
||||
const INACTIVE_COLOR := Color("d6b875")
|
||||
const SELECTED_COLOR := Color("f0d995")
|
||||
const BORDER_COLOR := Color("4c3a25")
|
||||
const TEXT_COLOR := Color("251b10")
|
||||
const DISABLED_COLOR := Color("aa9a76")
|
||||
const RISE_DURATION: float = UIMotion.UTILITY_ENTER_DURATION
|
||||
const INACTIVE_SETTLE_Y: float = 8.0
|
||||
const SELECTED_SETTLE_Y: float = 0.0
|
||||
const HOVER_SETTLE_Y: float = 4.0
|
||||
const HIDDEN_SETTLE_Y: float = 30.0
|
||||
|
||||
var _motion_tween: Tween
|
||||
var _hovered: bool = false
|
||||
var _motion_ready: bool = false
|
||||
var _visual_y: float = INACTIVE_SETTLE_Y
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
toggle_mode = true
|
||||
add_theme_font_override("font", UtilityPageStyle.TuffyFont)
|
||||
add_theme_font_size_override("font_size", 18)
|
||||
for color_name: StringName in [
|
||||
&"font_color",
|
||||
&"font_hover_color",
|
||||
&"font_focus_color",
|
||||
&"font_pressed_color",
|
||||
&"font_disabled_color",
|
||||
]:
|
||||
add_theme_color_override(color_name, Color.TRANSPARENT)
|
||||
mouse_entered.connect(_set_hovered.bind(true))
|
||||
mouse_exited.connect(_set_hovered.bind(false))
|
||||
focus_entered.connect(refresh_state)
|
||||
focus_exited.connect(refresh_state)
|
||||
toggled.connect(_on_toggled)
|
||||
_apply_empty_styles()
|
||||
call_deferred("_initialize_motion")
|
||||
|
||||
|
||||
func refresh_state(animate: bool = true) -> void:
|
||||
queue_redraw()
|
||||
if _motion_ready:
|
||||
_move_to_target(animate)
|
||||
|
||||
|
||||
func animate_entrance(delay: float = 0.0) -> void:
|
||||
_cancel_motion()
|
||||
_motion_ready = true
|
||||
_set_visual_y(HIDDEN_SETTLE_Y)
|
||||
_motion_tween = create_tween()
|
||||
if delay > 0.0:
|
||||
_motion_tween.tween_interval(delay)
|
||||
_motion_tween.tween_method(
|
||||
_set_visual_y, _visual_y, _target_y(), RISE_DURATION
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_OUT)
|
||||
_motion_tween.finished.connect(_clear_motion_tween, CONNECT_ONE_SHOT)
|
||||
|
||||
|
||||
func settle_for_close() -> void:
|
||||
_cancel_motion()
|
||||
if not _motion_ready:
|
||||
return
|
||||
_motion_tween = create_tween()
|
||||
_motion_tween.tween_method(
|
||||
_set_visual_y,
|
||||
_visual_y,
|
||||
HIDDEN_SETTLE_Y,
|
||||
UIMotion.UTILITY_EXIT_DURATION,
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN)
|
||||
_motion_tween.finished.connect(_clear_motion_tween, CONNECT_ONE_SHOT)
|
||||
|
||||
|
||||
func _initialize_motion() -> void:
|
||||
_motion_ready = true
|
||||
_set_visual_y(_target_y())
|
||||
|
||||
|
||||
func _on_toggled(_pressed: bool) -> void:
|
||||
refresh_state()
|
||||
|
||||
|
||||
func _set_hovered(hovered: bool) -> void:
|
||||
_hovered = hovered
|
||||
refresh_state()
|
||||
|
||||
|
||||
func _target_y() -> float:
|
||||
if button_pressed:
|
||||
return SELECTED_SETTLE_Y
|
||||
if _hovered or has_focus():
|
||||
return HOVER_SETTLE_Y
|
||||
return INACTIVE_SETTLE_Y
|
||||
|
||||
|
||||
func _move_to_target(animate: bool) -> void:
|
||||
_cancel_motion()
|
||||
if not animate:
|
||||
_set_visual_y(_target_y())
|
||||
return
|
||||
_motion_tween = create_tween()
|
||||
_motion_tween.tween_method(
|
||||
_set_visual_y, _visual_y, _target_y(), RISE_DURATION
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_OUT)
|
||||
_motion_tween.finished.connect(_clear_motion_tween, CONNECT_ONE_SHOT)
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
var base_color: Color = SELECTED_COLOR if button_pressed else INACTIVE_COLOR
|
||||
var border_width: int = 2
|
||||
var shadow_alpha: float = 0.28
|
||||
if disabled:
|
||||
base_color = DISABLED_COLOR
|
||||
border_width = 1
|
||||
shadow_alpha = 0.12
|
||||
elif has_focus():
|
||||
base_color = base_color.lightened(0.09)
|
||||
border_width = 4
|
||||
shadow_alpha = 0.40
|
||||
elif _hovered:
|
||||
base_color = base_color.lightened(0.07)
|
||||
border_width = 3
|
||||
shadow_alpha = 0.34
|
||||
var visual_rect := Rect2(Vector2(0.0, _visual_y), size)
|
||||
draw_style_box(
|
||||
_make_style(base_color, border_width, shadow_alpha),
|
||||
visual_rect,
|
||||
)
|
||||
var font: Font = UtilityPageStyle.TuffyFont
|
||||
var ink: Color = Color(TEXT_COLOR, 0.52) if disabled else TEXT_COLOR
|
||||
draw_string(
|
||||
font,
|
||||
Vector2(0.0, _visual_y + 32.0),
|
||||
text,
|
||||
HORIZONTAL_ALIGNMENT_CENTER,
|
||||
size.x,
|
||||
18,
|
||||
ink,
|
||||
)
|
||||
|
||||
|
||||
func _apply_empty_styles() -> void:
|
||||
for style_name: StringName in [
|
||||
&"normal",
|
||||
&"hover",
|
||||
&"focus",
|
||||
&"pressed",
|
||||
&"disabled",
|
||||
]:
|
||||
add_theme_stylebox_override(style_name, StyleBoxEmpty.new())
|
||||
|
||||
|
||||
func _set_visual_y(value: float) -> void:
|
||||
_visual_y = value
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _make_style(fill: Color, border_width: int, shadow_alpha: float) -> StyleBoxFlat:
|
||||
var style := StyleBoxFlat.new()
|
||||
style.bg_color = fill
|
||||
style.border_color = BORDER_COLOR
|
||||
style.border_width_left = border_width
|
||||
style.border_width_top = border_width
|
||||
style.border_width_right = border_width
|
||||
style.border_width_bottom = 1
|
||||
style.corner_radius_top_left = 13
|
||||
style.corner_radius_top_right = 13
|
||||
style.corner_radius_bottom_left = 2
|
||||
style.corner_radius_bottom_right = 2
|
||||
style.shadow_color = Color(0.12, 0.08, 0.04, shadow_alpha)
|
||||
style.shadow_size = 4
|
||||
style.shadow_offset = Vector2(0.0, 3.0)
|
||||
style.content_margin_left = 14.0
|
||||
style.content_margin_right = 14.0
|
||||
style.content_margin_top = 8.0
|
||||
style.content_margin_bottom = 12.0
|
||||
return style
|
||||
|
||||
|
||||
func _cancel_motion() -> void:
|
||||
if _motion_tween != null:
|
||||
_motion_tween.kill()
|
||||
_motion_tween = null
|
||||
|
||||
|
||||
func _clear_motion_tween() -> void:
|
||||
_motion_tween = null
|
||||
Loading…
Add table
Add a link
Reference in a new issue