1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
# Hurry Curry! - a game about cooking
# Copyright 2024 metamuffin
# Copyright 2024 tpart
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, version 3 of the License only.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name Menu
extends Control
#enum Anim { NONE, FADE }
#@export var animation: Anim = Anim.NONE
@export var support_anim := true
@export var auto_anim := true
var data
signal submenu_close()
const transition_scene = preload("res://menu/scene_transition.tscn")
var transition: SceneTransition
var parent_menu: Menu = null
var open_since = 0
func _ready():
open_since = Time.get_ticks_msec()
focus_first(self)
connect_button_sounds(self)
update_parent_menu(self.get_parent())
if support_anim: anim_setup()
if auto_anim: _menu_open()
func anim_setup():
transition = transition_scene.instantiate()
add_child(transition)
func _menu_open():
if transition != null: await transition.fade_in()
func _menu_exit():
if transition != null: await transition.fade_out()
func _menu_cover(_state: bool):
pass
var popup: Menu = null
var covered := false
func submenu(path: String, data_ = null):
var prev_focus = Global.focused_node
if popup != null: return
_disable_recursive(self, true)
covered = true
await _menu_cover(true)
popup = load(path).instantiate()
popup.data = data_
add_child(popup)
print("Submenu opened ", path)
await submenu_close
print("Submenu closed ", path)
await _menu_cover(false)
covered = false
_disable_recursive(self, false)
if prev_focus != null: prev_focus.grab_focus()
func _disable_recursive(node: Node, state: bool):
if node is BaseButton:
if state and node.disabled: node.add_to_group("was_disabled")
else: node.remove_from_group("was_disabled")
node.disabled = state or node.is_in_group("was_disabled")
for c in node.get_children(): _disable_recursive(c, state)
func exit():
await self._menu_exit()
get_parent().submenu_close.emit()
queue_free()
func quit():
await exit()
get_parent().quit()
func replace_menu(path: String):
print("Replace menu: ", path)
if popup != null: await popup.exit()
_disable_recursive(self, true)
await _menu_exit()
var new_popup = load(path).instantiate()
get_parent().add_child(new_popup)
if parent_menu != null: parent_menu.popup = new_popup
queue_free()
var focus_auto_changed := false
func focus_first(node: Node) -> bool:
focus_auto_changed = true
if node.is_in_group("no_auto_focus"):
return false
if node is Button or node is LineEdit:
node.grab_focus()
print("Node %s (%s) was selected for focus" % [node.name, node])
return true
for c in node.get_children():
if focus_first(c):
return true
return false
func connect_button_sounds(node: Node):
if node is Button or node is TextureButton:
if not node.is_in_group("no_click_sound"):
node.pressed.connect(Sound.play_click)
if (node is Button and not node.disabled) or (node is LineEdit and node.editable) or node is Slider:
node.mouse_entered.connect(Sound.play_hover)
for c in node.get_children():
connect_button_sounds(c)
func update_parent_menu(node: Node):
if node is Menu: parent_menu = node
elif node.get_parent() != null: update_parent_menu(node.get_parent())
func _input(_event):
if popup != null: return
if Time.get_ticks_msec() - open_since < 100: return
if Input.is_action_just_pressed("menu"):
Sound.play_click()
exit()
|