godot-demo-projects/3d/physics_tests/utils/option_menu.gd

61 lines
1.6 KiB
GDScript

class_name OptionMenu
extends MenuButton
signal option_selected(item_path)
signal option_changed(item_path, checked)
func add_menu_item(item_path, checkbox = false, checked = false):
var path_elements = item_path.split("/", false)
var path_element_count = path_elements.size()
assert(path_element_count > 0)
var path = ""
var popup = get_popup()
for element_index in range(path_element_count - 1):
var popup_label = path_elements[element_index]
path += popup_label + "/"
popup = _add_popup(popup, path, popup_label)
var label = path_elements[path_element_count - 1]
if checkbox:
popup.add_check_item(label)
popup.set_item_checked(popup.get_item_count() - 1, checked)
else:
popup.add_item(label)
func _add_item(parent_popup, label):
parent_popup.add_item(label)
func _add_popup(parent_popup, path, label):
if parent_popup.has_node(label):
var popup_node = parent_popup.get_node(label)
var popup_menu = popup_node as PopupMenu
assert(popup_menu)
return popup_menu
var popup_menu = PopupMenu.new()
popup_menu.name = label
popup_menu.hide_on_checkable_item_selection = false
parent_popup.add_child(popup_menu)
parent_popup.add_submenu_item(label, label)
popup_menu.connect(&"index_pressed", Callable(self, "_on_item_pressed"), [popup_menu, path])
return popup_menu
func _on_item_pressed(item_index, popup_menu, path):
var item_path = path + popup_menu.get_item_text(item_index)
if popup_menu.is_item_checkable(item_index):
var checked = not popup_menu.is_item_checked(item_index)
popup_menu.set_item_checked(item_index, checked)
emit_signal("option_changed", item_path, checked)
else:
emit_signal("option_selected", item_path)