Skip to content

Commit

Permalink
Add transitions between steps of guided tours
Browse files Browse the repository at this point in the history
This allows us to guide the user better during the
tour, making position changes between steps less
abrupt.
  • Loading branch information
YuriSizov committed Dec 25, 2024
1 parent 6bdb325 commit 8d21de1
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 28 deletions.
3 changes: 1 addition & 2 deletions globals/Controller.gd
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,7 @@ func get_info_popup() -> InfoPopup:


func show_window_popup(popup: WindowPopup, popup_size: Vector2) -> void:
popup.size = popup_size
popup.popup_anchored(Vector2(0.5, 0.5), PopupManager.Direction.OMNI, true)
popup.popup_anchored(Vector2(0.5, 0.5), popup_size, PopupManager.Direction.OMNI, true)


func show_welcome_message() -> void:
Expand Down
13 changes: 4 additions & 9 deletions globals/HelpManager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func _show_current_step() -> void:
return

_clear_trigger()
_info_popup.clear()
_info_popup.clear(true) # Avoid resetting size and position, as this breaks animations.

var step := _current_guide.steps[_current_step]
_info_popup.title = step.title
Expand All @@ -189,17 +189,12 @@ func _show_current_step() -> void:
else:
_info_popup.add_button("FINISH", _finish_guide)

# Resize, position, and show the popup.
# Resize, reposition, and show the popup.

_info_popup.size = step.size
if _info_popup.is_popped():
# TODO: It would be nice to have these transitions animated, but that requires additional work.
# The final size and the final position are calculated behind the scenes as we adjust anchors.
# Working around this would require us to replicate anchor calculations in scripts, and then
# change position instead. Maybe some day...
_info_popup.move_anchored(step.position_anchor, step.position_direction)
_info_popup.transform_anchored(step.position_anchor, step.size, step.position_direction)
else:
_info_popup.popup_anchored(step.position_anchor, step.position_direction, false)
_info_popup.popup_anchored(step.position_anchor, step.size, step.position_direction, false)

# Navigate to the target view and highlight the target control, if there is one.
Controller.navigate_to(step.navigation_target)
Expand Down
41 changes: 35 additions & 6 deletions globals/PopupManager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func create_anchored_popup(popup: PopupControl, anchor_position: Vector2, direct
_click_catcher.visible = true


func translate_popup(popup: PopupControl, delta: Vector2) -> void:
func adjust_popup_position(popup: PopupControl, delta: Vector2) -> void:
if not has_popup(popup):
printerr("PopupManager: Popup %s is not shown." % [ popup ])
return
Expand All @@ -131,14 +131,21 @@ func translate_popup(popup: PopupControl, delta: Vector2) -> void:
anchor.update_absolute_position(next_position, popup.size, popup._last_direction)


func translate_anchored_popup(popup: PopupControl, anchor_position: Vector2, direction: Direction) -> void:
func transform_anchored_popup(popup: PopupControl, anchor_position: Vector2, popup_size: Vector2, direction: Direction, smooth: bool = false) -> void:
if not has_popup(popup):
printerr("PopupManager: Popup %s is not shown." % [ popup ])
return

var original_position := popup.global_position
var original_size := popup.size

popup.size = popup_size
var anchor := popup.get_popup_anchor()
anchor.update_relative_position(anchor_position, popup.size, direction)
anchor.update_relative_position(anchor_position, popup_size, direction)
popup.align_popup(direction)

if smooth:
popup.animate_transform(original_position, original_size)


func has_popup(popup: PopupControl) -> bool:
Expand Down Expand Up @@ -184,14 +191,14 @@ static func move_popup(popup: PopupControl, delta: Vector2) -> void:
if not _instance:
return

_instance.translate_popup(popup, delta)
_instance.adjust_popup_position(popup, delta)


static func move_popup_anchored(popup: PopupControl, anchor_position: Vector2, direction: Direction) -> void:
static func transform_popup_anchored(popup: PopupControl, anchor_position: Vector2, popup_size: Vector2, direction: Direction, smooth: bool = false) -> void:
if not _instance:
return

_instance.translate_anchored_popup(popup, anchor_position, direction)
_instance.transform_anchored_popup(popup, anchor_position, popup_size, direction, smooth)


static func hide_popup(popup: PopupControl) -> void:
Expand Down Expand Up @@ -229,7 +236,10 @@ class PopupControl extends Control:
signal about_to_popup()
signal about_to_hide()

const TRANSFORM_DURATION := 0.18

var _last_direction: Direction = Direction.BOTTOM_RIGHT
var _tween: Tween = null


# Input events.
Expand Down Expand Up @@ -272,6 +282,25 @@ class PopupControl extends Control:
set_anchors_and_offsets_preset(Control.PRESET_CENTER, Control.PRESET_MODE_KEEP_SIZE)
grow_horizontal = Control.GROW_DIRECTION_BOTH
grow_vertical = Control.GROW_DIRECTION_BOTH


func animate_transform(original_position: Vector2, original_size: Vector2) -> void:
# We immediately reset position and size to their old values. This all
# happens in the same frame, so it should be seamless. New position and
# size are our tweening targets.

var target_position := global_position
var target_size := size

global_position = original_position
size = original_size

if _tween:
_tween.kill()

_tween = get_tree().create_tween().set_parallel()
_tween.tween_property(self, "global_position", target_position, TRANSFORM_DURATION)
_tween.tween_property(self, "size", target_size, TRANSFORM_DURATION)


class PopupAnchor extends Control:
Expand Down
4 changes: 2 additions & 2 deletions gui/widgets/popups/IOConfigPopup.gd
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ func _notification(what: int) -> void:
# Lifecycle.

## Override.
func clear() -> void:
func clear(keep_size: bool = false) -> void:
activate_view(View.NONE)

super()
super(keep_size)


# Config views.
Expand Down
4 changes: 2 additions & 2 deletions gui/widgets/popups/InfoPopup.gd
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func _ready() -> void:
# Lifecycle.

## Override.
func clear() -> void:
func clear(keep_size: bool = false) -> void:
content = ""
_ref_image = null
_ref_image_size = Vector2.ZERO
Expand All @@ -43,7 +43,7 @@ func clear() -> void:
if is_node_ready():
_update_image()

super()
super(keep_size)


# Content.
Expand Down
16 changes: 9 additions & 7 deletions gui/widgets/popups/WindowPopup.gd
Original file line number Diff line number Diff line change
Expand Up @@ -109,27 +109,29 @@ func is_popped() -> bool:
return PopupManager.is_popup_shown(self)


func popup_anchored(anchor_position: Vector2, direction: PopupManager.Direction = PopupManager.Direction.BOTTOM_RIGHT, blocking: bool = true) -> void:
func popup_anchored(anchor_position: Vector2, popup_size: Vector2, direction: PopupManager.Direction = PopupManager.Direction.BOTTOM_RIGHT, blocking: bool = true) -> void:
size = popup_size
_update_before_popup()
PopupManager.show_popup_anchored(self, anchor_position, direction, blocking)


func move_anchored(anchor_position: Vector2, direction: PopupManager.Direction = PopupManager.Direction.BOTTOM_RIGHT) -> void:
PopupManager.move_popup_anchored(self, anchor_position, direction)
func transform_anchored(anchor_position: Vector2, popup_size: Vector2, direction: PopupManager.Direction = PopupManager.Direction.BOTTOM_RIGHT) -> void:
PopupManager.transform_popup_anchored(self, anchor_position, popup_size, direction, true)


func close_popup() -> void:
mark_click_handled()
PopupManager.hide_popup(self)


func clear() -> void:
func clear(keep_size: bool = false) -> void:
title = DEFAULT_TITLE
_clear_buttons()

custom_minimum_size = Vector2.ZERO
set_anchors_and_offsets_preset(Control.PRESET_TOP_LEFT, Control.PRESET_MODE_MINSIZE)
size = Vector2.ZERO
if not keep_size:
custom_minimum_size = Vector2.ZERO
set_anchors_and_offsets_preset(Control.PRESET_TOP_LEFT, Control.PRESET_MODE_MINSIZE)
size = Vector2.ZERO


# Content.
Expand Down

0 comments on commit 8d21de1

Please sign in to comment.