123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- class_name Show
- extends Node2D
- # Manage slide cycling
- signal end_reached
- const VOID_SLIDE_ID := -1
- @export_group("Slide management")
- @export var start_slide := 0
- @export var hide_slides := false
- @export_group("Input setup", "action_")
- @export var action_finish_slide := "ui_accept"
- @export var action_skip_slide := "ui_right"
- @export var action_previous_slide := "ui_left"
- @export var action_home_slide := "ui_cancel"
- @export_group("Export")
- @export var one_slide_per_frame := true
- @export var quit_after_last_slide := true
- var current_id := VOID_SLIDE_ID
- var current_slide: Slide
- @onready var focus: Focus = $"../Focus"
- @onready var slides: Array = get_children()
- @onready var movie_enabled: bool = OS.has_feature("movie")
- @onready var auto_next_slide: bool = movie_enabled and one_slide_per_frame
- func _ready() -> void:
- _enforce()
- print("The show contains %s slides" % slides.size())
- if hide_slides:
- _hide_every_slide()
- _global_slide_setup()
- if auto_next_slide:
- end_reached.connect(get_tree().quit)
- return
- go_slowly_to_next_slide()
- func _process(_delta: float) -> void:
- if auto_next_slide:
- go_fast_to_next_slide()
- func go_slowly_to_next_slide() -> void:
- next_slide(Focus.Transit.SMOOTH)
- func go_fast_to_next_slide() -> void:
- next_slide(Focus.Transit.BEAM)
- func go_fast_to_previous_slide() -> void:
- next_slide_at(_previous_id(), Focus.Transit.BEAM)
- func next_slide(trans: Focus.Transit) -> void:
- next_slide_at(_next_id(), trans)
- func next_slide_at(next_id: int, trans: Focus.Transit) -> void:
- _disable_current_slide()
- current_id = next_id
- current_slide = _focus_slide(current_id, trans)
- if is_last_slide():
- end_reached.emit()
- _enable_current_slide()
- func is_last_slide() -> bool:
- return current_id == slides.size() - 1
- func _focus_slide(id: int, trans: Focus.Transit) -> Slide:
- var slide: Slide = slides[id]
- focus.focus_on(slide.get_center(), slide.get_scale().x, trans)
- return slide
- func _hide_every_slide() -> void:
- for slide in slides:
- slide.gently_hide()
- func _global_slide_setup() -> void:
- for slide in slides:
- slide.set_action_finish(action_finish_slide)
- func _disable_current_slide() -> void:
- if current_slide != null:
- current_slide.disable()
- current_slide.finished.disconnect(_on_current_slide_finished)
- func _enable_current_slide() -> void:
- current_slide.enable()
- current_slide.finished.connect(_on_current_slide_finished)
- func _enforce() -> void:
- _enforce_parameters()
- _enforce_children()
- func _enforce_parameters() -> void:
- assert(focus, "A Focus node must be next to the Show node")
- assert(start_slide >= 0,
- "Negative index is not supported for start_slide")
- assert(start_slide < slides.size(),
- "start_slide index is out of bound (max is %s)" % (slides.size() - 1))
- func _enforce_children() -> void:
- assert(!slides.is_empty(), "A slideshow must contain slides")
- for object in slides:
- assert(object is Slide, "A slideshow can only contain slides but encontered %s" % object)
- func _next_id() -> int:
- if current_id == VOID_SLIDE_ID:
- return start_slide
- elif is_last_slide():
- return 0
- return current_id + 1
- func _previous_id() -> int:
- var next_id: int = current_id - 1
- if next_id < 0:
- return slides.size() - 1
- return next_id
- func _reset_id() -> void:
- current_id = VOID_SLIDE_ID
- func _unhandled_key_input(event: InputEvent) -> void:
- if !event.is_pressed():
- return
- if event.is_action(action_skip_slide):
- get_viewport().set_input_as_handled()
- go_fast_to_next_slide()
- elif event.is_action(action_previous_slide):
- get_viewport().set_input_as_handled()
- go_fast_to_previous_slide()
- elif event.is_action(action_home_slide):
- get_viewport().set_input_as_handled()
- _reset_id()
- go_slowly_to_next_slide()
- func _unhandled_input(event: InputEvent) -> void:
- if event is InputEventMouseButton and event.is_pressed():
- _focus_nearest_slide_from(get_global_mouse_position())
- func _focus_nearest_slide_from(target_pos: Vector2) -> void:
- var next_slide = _search_nearest_slide_from(target_pos)
- var next_id = slides.find(next_slide)
- next_slide_at(next_id, Focus.Transit.SMOOTH)
- func _search_nearest_slide_from(target_pos: Vector2) -> Slide:
- var nearest_slide = current_slide
- var shortest_distance = target_pos.distance_squared_to(nearest_slide.get_center())
- for current_slide in slides:
- var current_distance = target_pos.distance_squared_to(current_slide.get_center())
- if current_distance < shortest_distance:
- nearest_slide = current_slide
- shortest_distance = current_distance
- return nearest_slide
- func _on_current_slide_finished() -> void:
- go_slowly_to_next_slide()
|