Show.gd 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. class_name Show
  2. extends Node2D
  3. # Manage slide cycling
  4. signal new_focus(pos: Vector2, scale: float)
  5. signal slow_move
  6. signal fast_move
  7. const VOID_SLIDE_ID := -1
  8. @export var start_slide := 0
  9. var current_id := VOID_SLIDE_ID
  10. var current_slide: Slide
  11. @onready var slides: Array = get_children()
  12. func _ready() -> void:
  13. _enforce()
  14. hide_every_slide()
  15. go_slowly_to_next_slide()
  16. func go_slowly_to_next_slide() -> void:
  17. _next_slide()
  18. slow_move.emit()
  19. func go_fast_to_next_slide() -> void:
  20. _next_slide()
  21. fast_move.emit()
  22. func _next_slide() -> void:
  23. _next_slide_at(_next_id())
  24. func _next_slide_at(next_id: int) -> void:
  25. _disconnect_current_slide()
  26. current_id = next_id
  27. current_slide = focus_slide(current_id)
  28. _connect_current_slide()
  29. func focus_slide(id: int) -> Slide:
  30. var slide: Slide = slides[id]
  31. slide.focus()
  32. new_focus.emit(slide.get_center(), slide.get_scale().x)
  33. return slide
  34. func hide_every_slide() -> void:
  35. for slide in slides:
  36. slide.gently_hide()
  37. func _disconnect_current_slide() -> void:
  38. if current_slide != null:
  39. current_slide.remove_focus()
  40. current_slide.finished.disconnect(_on_current_slide_finished)
  41. func _connect_current_slide() -> void:
  42. current_slide.finished.connect(_on_current_slide_finished)
  43. func _enforce() -> void:
  44. _enforce_parameters()
  45. _enforce_children()
  46. func _enforce_parameters() -> void:
  47. assert(start_slide >= 0,
  48. "Negative index is not supported for start_slide")
  49. assert(start_slide < slides.size(),
  50. "start_slide index is out of bound (max is %s)" % (slides.size() - 1))
  51. func _enforce_children() -> void:
  52. assert(!slides.is_empty(), "A slideshow must contain slides")
  53. for slide in slides:
  54. assert(slide is Slide, "A slideshow can only contain slides")
  55. func _next_id() -> int:
  56. if current_id == VOID_SLIDE_ID:
  57. return start_slide
  58. var next_id: int = current_id + 1
  59. if next_id >= slides.size():
  60. return 0
  61. return next_id
  62. func _reset_id() -> void:
  63. current_id = VOID_SLIDE_ID
  64. func _unhandled_key_input(event: InputEvent) -> void:
  65. if !event.is_pressed():
  66. return
  67. if event.is_action("ui_right"):
  68. get_viewport().set_input_as_handled()
  69. go_fast_to_next_slide()
  70. elif event.is_action("ui_cancel"):
  71. get_viewport().set_input_as_handled()
  72. _reset_id()
  73. go_slowly_to_next_slide()
  74. func _unhandled_input(event: InputEvent) -> void:
  75. if event is InputEventMouseButton and event.is_pressed():
  76. var gpos: Vector2 = get_global_mouse_position()
  77. var nearest_slide = current_slide
  78. var shortest_distance = gpos.distance_squared_to(nearest_slide.get_center())
  79. for current_slide in slides:
  80. var current_distance = gpos.distance_squared_to(current_slide.get_center())
  81. if current_distance < shortest_distance:
  82. nearest_slide = current_slide
  83. shortest_distance = current_distance
  84. var next_id = slides.find(nearest_slide)
  85. _next_slide_at(next_id)
  86. slow_move.emit()
  87. func _on_current_slide_finished() -> void:
  88. go_slowly_to_next_slide()