From 960ed412d999460e4ef83e99a7b3c010f9fa4a1a Mon Sep 17 00:00:00 2001 From: betalars Date: Sun, 25 Jun 2023 22:40:31 +0200 Subject: [PATCH] refactoring focus handling in global state --- src/singletons/global_state.gd | 93 ++++++++++++++++------------------ 1 file changed, 45 insertions(+), 48 deletions(-) diff --git a/src/singletons/global_state.gd b/src/singletons/global_state.gd index e5d38be3..16ff66fc 100644 --- a/src/singletons/global_state.gd +++ b/src/singletons/global_state.gd @@ -12,57 +12,54 @@ var allow_skipping: bool = false var focus_list:Array = [] var lock_focus: bool = false -func request_focus(new_focus: Node, reclaim_focus: bool = false) -> bool: - - assert(is_instance_valid(new_focus)) +# Intented for use when me wants focus for itself, can reclaim focus, thus dropping the stack that focused. +func request_focus_for(me: Object, reclaim: bool = false) -> bool: + if reclaim: + focus_list.front().has_focus = false + if focus_list.has(me): + while focus_list.pop_front() != me: break + me.has_focus = true + return me.has_focus + push_warning(me, " wanted to reclaim focus, but was not on list.") + return pass_focus_to(me) + +# Element no longer wants focus, if Element itself is also dropped, this option can be chosen aswell. +func drop_focus(of:Object, dropObject: bool = false) -> bool: if lock_focus or get_tree().paused: - push_warning(new_focus.name, " attempted to get focus while tree was paused or fokus had been locked.") - return false + push_error(of, " wanted to drop focus while it was locked or tree is paused.") - if not focus_list.size() == 0: _pass_focus_of(focus_list[0]) + if not dropObject: of.has_focus = false - if reclaim_focus: - if focus_list.has(new_focus): - while not focus_list[0] == new_focus: focus_list.pop_front() - return true - else: - focus_list.push_front(new_focus) - push_warning(new_focus.name, " attempted to reclaim focus it did not previousely have.") - return true + focus_list.erase(of) + + focus_list.front().has_focus = true + + return false + +func get_current_focus(): return focus_list.front() + +# Used to put a new target on top of the Focus Stack. +func pass_focus_to(target:Object) -> bool: + if "focus_forward" in target: + pass_focus_to(target.focus_forward) + 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") + elif !"has_focus" in target: + push_error(target, " has no has focus method") else: - focus_list.append(new_focus) - return true + if not focus_list.front() == null: focus_list.front().has_focus = false + target.has_focus = true + if target.has_focus: + focus_list.push_front(target) + assert(focus_list.size() < 100) + return true + return false -func assign_focus_to(focusable: Node) -> bool: - if "focus_forward" in focusable: - assign_focus_to(focusable.focus_forward) - if "has_focus" in focusable: - if not focus_list.size() == 0: - _pass_focus_of(focus_list[0]) - focusable.has_focus = true - return true - else: return false +# Currently focused element loses focus, but remains in stack. +func free_focus(): + if not focus_list.front() == null: focus_list.front().has_focus = false -func pass_focus_to_unkown(from: Node): - pass - -func drop_own_focus(node: Node): - if focus_list[0] == node: - focus_list.pop_front().has_focus = false - assert(focus_list.size() == 0) - focus_list[0].has_focus = true - else: - push_warning(node.name + " attempted to drop focus while not owning it.") - -func clear_focus_stack_and_focus_on(focus: Node): - assert(is_instance_valid(focus)) - if focus_list.size() > 0: focus_list[0].has_focus = false - focus_list = [focus] - focus.has_focus = true - -func _pass_focus_of(previous_focus: Node): - previous_focus.has_focus = false - -func focus_cleared(from: Node): - if from == focus_list[0]: - push_warning(from.name, " cleared focus without validating!") +func queue_for_focus(target: Object, index: int): + focus_list.insert(index, target)