extends Node # For Startup Scene: var screen_reader:bool = false # Screenreader var disable_rendering: bool = false # show nav button var simplified_navigation:bool = false # simplified controls var show_navigation_buttons: bool = false # show nav ui var enable_subtitles: bool = false # ItemList2 var enable_closed_caption: bool = false # ItemList2 var reduce_motion: bool = false # ? var streaming_content_notes: bool = false # continue/CheckBox var show_content_notes: bool = false # ContentNotes/.../Checkbox var provide_summaries: bool = false # ContentNotes/.../Checkbox2 var allow_skipping: bool = false var stage_list:Array = [] var lock_focus: bool = false func _ready(): for child in get_parent().get_children(): if "has_stage" in child: pass_stage_to(child) # Meta: due to conflicting names with the internal focus handling of godot, a "stage-based" Metaphor is being used to refer to focus handling. # Intented for use when an actor wants focus for itself, can reclaim focus, thus dropping the stack that focused. func take_stage(actor: Object, reclaim: bool = false) -> bool: if lock_focus: return false if reclaim: stage_list.front().has_stage = false if stage_list.has(actor): while stage_list.pop_front() != actor: break actor.has_stage = true stage_list.push_front(actor) return actor.has_stage push_warning(actor, " wanted to reclaim focus, but was not on list.") return pass_stage_to(actor) # Element no longer wants focus, if Element itself is also dropped, this option can be chosen aswell. func leave_stage(actor:Object, dropObject: bool = false) -> bool: if get_tree().paused: push_error(actor, " wanted to drop focus while tree is paused.") if not dropObject: actor.has_stage = false lock_focus = false stage_list.erase(actor) if stage_list != []: stage_list.front().has_stage = true else: get_tree().quit() return false func get_current_actor(): return stage_list.front() # Used to put a new target on top of the Focus Stack. func pass_stage_to(target:Object, force = false) -> bool: if "pass_to_actor" in target: pass_stage_to(target.pass_to_actor) if (lock_focus or get_tree().paused) and not force: push_error(target, " requested focus while it was locked or tree is paused.") elif !is_instance_valid(target): push_error("Focus instance not valid") elif !"has_stage" in target: push_error(target, " has no has focus method.") else: if stage_list.size() > 0: if stage_list.front() == target: push_warning(target, " is already target. Abort passing focus.") return false if not stage_list.size() == 0: stage_list.front().has_stage = false target.has_stage = true if target.has_stage: stage_list.push_front(target) assert(stage_list.size() < 100) return true return false # Currently focused element loses focus, but remains in stack. func free_focus(): if lock_focus: return false if stage_list.size() > 0: stage_list.front().has_stage = false func transition_stage_to(thief: Object): if stage_list.size() > 0: if stage_list.front().has_stage: stage_list.pop_front().has_stage = false return pass_stage_to(thief, true) func queue_for_stage(target: Object, index: int = 1): stage_list.insert(index, target) func print_settings(): print_debug("Screenreader: ", screen_reader, " / ", "Disable rendering: ", disable_rendering, " / ", "Simplified controls: ", simplified_navigation, " / ", "Show navigation buttons: ", show_navigation_buttons, " / ", "Enable subtitles: ", enable_subtitles, " / ", "Enable CC: ", enable_closed_caption, " / ")