2023-03-09 21:54:22 +00:00
|
|
|
extends Node
|
|
|
|
|
|
|
|
|
|
var screen_reader:bool = false
|
|
|
|
|
var disable_rendering: bool = false
|
|
|
|
|
var simplified_navigation:bool = false
|
|
|
|
|
var enable_subtitles: bool = false
|
|
|
|
|
var reduce_motion: bool = false
|
|
|
|
|
var show_content_notes: bool = false
|
2023-04-15 14:01:22 +00:00
|
|
|
var provide_summaries: bool = false
|
|
|
|
|
var allow_skipping: bool = false
|
|
|
|
|
|
2023-07-11 13:27:44 +00:00
|
|
|
var stage_list:Array = []
|
2023-04-22 13:11:10 +00:00
|
|
|
var lock_focus: bool = false
|
2023-04-15 14:01:22 +00:00
|
|
|
|
2023-06-30 23:14:25 +00:00
|
|
|
func _ready():
|
|
|
|
|
for child in get_parent().get_children():
|
2023-07-11 13:27:44 +00:00
|
|
|
if "has_stage" in child:
|
|
|
|
|
pass_stage_to(child)
|
2023-06-30 23:14:25 +00:00
|
|
|
|
2023-07-11 13:27:44 +00:00
|
|
|
# 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:
|
2023-06-25 20:40:31 +00:00
|
|
|
if reclaim:
|
2023-07-11 13:27:44 +00:00
|
|
|
stage_list.front().has_stage = false
|
|
|
|
|
if stage_list.has(actor):
|
|
|
|
|
while stage_list.pop_front() != actor: break
|
|
|
|
|
actor.has_stage = true
|
|
|
|
|
return actor.has_stage
|
|
|
|
|
push_warning(actor, " wanted to reclaim focus, but was not on list.")
|
|
|
|
|
return pass_stage_to(actor)
|
2023-06-25 20:40:31 +00:00
|
|
|
|
|
|
|
|
# Element no longer wants focus, if Element itself is also dropped, this option can be chosen aswell.
|
2023-07-11 13:27:44 +00:00
|
|
|
func leave_stage(actor:Object, dropObject: bool = false) -> bool:
|
2023-05-18 07:40:52 +00:00
|
|
|
if lock_focus or get_tree().paused:
|
2023-07-11 13:27:44 +00:00
|
|
|
push_error(actor, " wanted to drop focus while it was locked or tree is paused.")
|
2023-05-18 07:40:52 +00:00
|
|
|
|
2023-07-11 13:27:44 +00:00
|
|
|
if not dropObject: actor.has_stage = false
|
2023-05-18 07:40:52 +00:00
|
|
|
|
2023-07-11 13:27:44 +00:00
|
|
|
stage_list.erase(actor)
|
2023-04-15 14:01:22 +00:00
|
|
|
|
2023-07-11 13:27:44 +00:00
|
|
|
stage_list.front().has_stage = true
|
2023-06-25 20:40:31 +00:00
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
2023-07-11 13:27:44 +00:00
|
|
|
func get_current_actor(): return stage_list.front()
|
2023-05-18 07:40:52 +00:00
|
|
|
|
2023-06-25 20:40:31 +00:00
|
|
|
# Used to put a new target on top of the Focus Stack.
|
2023-07-11 13:27:44 +00:00
|
|
|
func pass_stage_to(target:Object) -> bool:
|
|
|
|
|
if "pass_to_actor" in target:
|
|
|
|
|
pass_stage_to(target.pass_to_actor)
|
2023-06-25 20:40:31 +00:00
|
|
|
if lock_focus or get_tree().paused:
|
|
|
|
|
push_error(target, " requested focus while it was locked or tree is paused.")
|
|
|
|
|
elif !is_instance_valid(target):
|
|
|
|
|
push_error("Focus instance not valid")
|
2023-07-11 13:27:44 +00:00
|
|
|
elif !"has_stage" in target:
|
2023-06-30 23:14:25 +00:00
|
|
|
push_error(target, " has no has focus method.")
|
2023-07-11 13:27:44 +00:00
|
|
|
if stage_list.size() > 0:
|
|
|
|
|
if stage_list.front() == target:
|
2023-07-08 20:06:06 +00:00
|
|
|
push_warning(target, " is already target. Abort passing focus.")
|
2023-04-15 14:01:22 +00:00
|
|
|
else:
|
2023-07-11 13:27:44 +00:00
|
|
|
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)
|
2023-06-25 20:40:31 +00:00
|
|
|
return true
|
|
|
|
|
return false
|
2023-05-18 07:40:52 +00:00
|
|
|
|
2023-06-25 20:40:31 +00:00
|
|
|
# Currently focused element loses focus, but remains in stack.
|
|
|
|
|
func free_focus():
|
2023-07-11 13:27:44 +00:00
|
|
|
if not stage_list.front() == null: stage_list.front().has_stage = false
|
2023-06-25 20:40:31 +00:00
|
|
|
|
2023-07-11 13:27:44 +00:00
|
|
|
func queue_for_stage(target: Object, index: int):
|
|
|
|
|
stage_list.insert(index, target)
|