Show.gd 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. class_name Show
  2. extends Node2D
  3. # Manage slide cycling
  4. signal new_focus(pos: Vector2, scale: float, trans: Focus.Transit)
  5. const VOID_SLIDE_ID := -1
  6. @export var start_slide := 0
  7. @export var hide_slides := false
  8. var current_id := VOID_SLIDE_ID
  9. var current_slide: Slide
  10. @onready var slides: Array = get_children()
  11. func _ready() -> void:
  12. _enforce()
  13. print("The show contains %s slides" % slides.size())
  14. if hide_slides:
  15. _hide_every_slide()
  16. go_slowly_to_next_slide()
  17. func go_slowly_to_next_slide() -> void:
  18. next_slide(Focus.Transit.SMOOTH)
  19. func go_fast_to_next_slide() -> void:
  20. next_slide(Focus.Transit.BEAM)
  21. func go_fast_to_previous_slide() -> void:
  22. next_slide_at(_previous_id(), Focus.Transit.BEAM)
  23. func next_slide(trans: Focus.Transit) -> void:
  24. next_slide_at(_next_id(), trans)
  25. func next_slide_at(next_id: int, trans: Focus.Transit) -> void:
  26. _disable_current_slide()
  27. current_id = next_id
  28. current_slide = _focus_slide(current_id, trans)
  29. _enable_current_slide()
  30. func _focus_slide(id: int, trans: Focus.Transit) -> Slide:
  31. var slide: Slide = slides[id]
  32. new_focus.emit(slide.get_center(), slide.get_scale().x, trans)
  33. return slide
  34. func _hide_every_slide() -> void:
  35. for slide in slides:
  36. slide.gently_hide()
  37. func _disable_current_slide() -> void:
  38. if current_slide != null:
  39. current_slide.disable()
  40. current_slide.finished.disconnect(_on_current_slide_finished)
  41. func _enable_current_slide() -> void:
  42. current_slide.enable()
  43. current_slide.finished.connect(_on_current_slide_finished)
  44. func _enforce() -> void:
  45. _enforce_parameters()
  46. _enforce_children()
  47. func _enforce_parameters() -> void:
  48. assert(start_slide >= 0,
  49. "Negative index is not supported for start_slide")
  50. assert(start_slide < slides.size(),
  51. "start_slide index is out of bound (max is %s)" % (slides.size() - 1))
  52. func _enforce_children() -> void:
  53. assert(!slides.is_empty(), "A slideshow must contain slides")
  54. for slide in slides:
  55. assert(slide is Slide, "A slideshow can only contain slides")
  56. func _next_id() -> int:
  57. if current_id == VOID_SLIDE_ID:
  58. return start_slide
  59. var next_id: int = current_id + 1
  60. if next_id >= slides.size():
  61. return 0
  62. return next_id
  63. func _previous_id() -> int:
  64. var next_id: int = current_id - 1
  65. if next_id < 0:
  66. return slides.size() - 1
  67. return next_id
  68. func _reset_id() -> void:
  69. current_id = VOID_SLIDE_ID
  70. func _unhandled_key_input(event: InputEvent) -> void:
  71. if !event.is_pressed():
  72. return
  73. if event.is_action("ui_right"):
  74. get_viewport().set_input_as_handled()
  75. go_fast_to_next_slide()
  76. elif event.is_action("ui_left"):
  77. get_viewport().set_input_as_handled()
  78. go_fast_to_previous_slide()
  79. elif event.is_action("ui_cancel"):
  80. get_viewport().set_input_as_handled()
  81. _reset_id()
  82. go_slowly_to_next_slide()
  83. func _unhandled_input(event: InputEvent) -> void:
  84. if event is InputEventMouseButton and event.is_pressed():
  85. _focus_nearest_slide_from(get_global_mouse_position())
  86. func _focus_nearest_slide_from(target_pos: Vector2) -> void:
  87. var next_slide = _search_nearest_slide_from(target_pos)
  88. var next_id = slides.find(next_slide)
  89. next_slide_at(next_id, Focus.Transit.SMOOTH)
  90. func _search_nearest_slide_from(target_pos: Vector2) -> Slide:
  91. var nearest_slide = current_slide
  92. var shortest_distance = target_pos.distance_squared_to(nearest_slide.get_center())
  93. for current_slide in slides:
  94. var current_distance = target_pos.distance_squared_to(current_slide.get_center())
  95. if current_distance < shortest_distance:
  96. nearest_slide = current_slide
  97. shortest_distance = current_distance
  98. return nearest_slide
  99. func _on_current_slide_finished() -> void:
  100. go_slowly_to_next_slide()