Skip to content

Instantly share code, notes, and snippets.

@DaelonSuzuka
Last active February 16, 2022 15:22
Show Gist options
  • Save DaelonSuzuka/9efe6143f7f136f55e2a0d5d76b6d094 to your computer and use it in GitHub Desktop.
Save DaelonSuzuka/9efe6143f7f136f55e2a0d5d76b6d094 to your computer and use it in GitHub Desktop.
MenuButton.gd
extends Control
# ******************************************************************************
onready var MenuButton = find_node('MenuButton')
# ******************************************************************************
func _ready():
# Add an optional callback when you create a menu item
# format is an Array in a similar format as the connect() function:
# [object, 'method_name', <optional_argument>]
MenuButton.add_item('item 1', [self, 'test'])
MenuButton.add_item('item 2', [self, 'test2'])
MenuButton.create_submenu('Test Submenu', 'TestSubmenu')
MenuButton.add_submenu_item('sub 1', 'TestSubmenu', [self, 'submenu', 1])
MenuButton.add_submenu_item('sub 2', 'TestSubmenu', [self, 'submenu', 2])
MenuButton.add_submenu_item('sub 3', 'TestSubmenu', [self, 'submenu', 3])
# alternately, connect to the item_selected signal
# this signal returns the full "path" of the selected item
# "item_name"
# "submenu_name/item_name"
MenuButton.connect('item_selected', self, 'on_item_selected')
func on_item_selected(item):
print(item)
if item.begins_with('TestSubmenu/'):
print('user clicked in submenu')
match item:
'item 1':
print('handle item 1')
'item 2':
print('handle item 2')
func test():
print('test')
func test2():
print('test2')
func submenu(value):
print('submenu:', value)
tool
extends MenuButton
# ******************************************************************************
onready var popup:PopupMenu = get_popup()
var callbacks := {}
signal item_selected(item)
# ******************************************************************************
func _ready() -> void:
popup.connect('index_pressed', self, '_on_index_pressed')
func create_submenu(label:String, submenu_name:String) -> PopupMenu:
var submenu:PopupMenu = PopupMenu.new()
submenu.name = submenu_name
submenu.connect('index_pressed', self, '_on_index_pressed', [submenu_name])
popup.add_child(submenu)
popup.add_submenu_item(label, submenu_name)
return submenu
func add_item(label: String, cb:=[]) -> void:
popup.add_item(label)
if cb:
callbacks[label] = cb
func add_check_item(label: String, cb:=[]):
popup.add_check_item(label)
if cb:
callbacks[label] = cb
func set_item_checked(item_text, state):
for i in popup.get_item_count():
if popup.get_item_text(i) == item_text:
if popup.is_item_checked(i) != state:
popup.toggle_item_checked(i)
return
func add_submenu_item(label:String, submenu_name:String, cb:=[]) -> void:
var submenu:PopupMenu = popup.get_node(submenu_name)
submenu.add_item(label)
if cb:
callbacks[submenu_name + '/' + label] = cb
func _on_index_pressed(idx:int, submenu_name:='') -> void:
var menu = popup
var item = ''
if submenu_name:
menu = popup.get_node(submenu_name)
item += menu.name + '/'
item += menu.get_item_text(idx)
if item in callbacks:
var cb = callbacks[item]
var obj = cb[0]
var method = cb[1]
if obj.has_method(method):
if menu.is_item_checkable(idx):
menu.toggle_item_checked(idx)
var checked = menu.is_item_checked(idx)
if len(cb) == 2:
obj.call(method, checked)
if len(cb) == 3:
obj.call(method, checked, cb[2])
else:
if len(cb) == 2:
obj.call(method)
if len(cb) == 3:
obj.call(method, cb[2])
emit_signal('item_selected', item)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment