option_menu.gd 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. class_name OptionMenu
  2. extends MenuButton
  3. signal option_selected(item_path)
  4. signal option_changed(item_path, checked)
  5. func add_menu_item(item_path, checkbox = false, checked = false, radio = false):
  6. var path_elements = item_path.split("/", false)
  7. var path_element_count = path_elements.size()
  8. assert(path_element_count > 0)
  9. var path = ""
  10. var popup = get_popup()
  11. for element_index in range(path_element_count - 1):
  12. var popup_label = path_elements[element_index]
  13. path += popup_label + "/"
  14. popup = _add_popup(popup, path, popup_label)
  15. var label = path_elements[path_element_count - 1]
  16. if radio:
  17. popup.add_radio_check_item(label)
  18. popup.set_item_checked(popup.get_item_count() - 1, checked)
  19. elif checkbox:
  20. popup.add_check_item(label)
  21. popup.set_item_checked(popup.get_item_count() - 1, checked)
  22. else:
  23. popup.add_item(label)
  24. func _add_item(parent_popup, label):
  25. parent_popup.add_item(label)
  26. func _add_popup(parent_popup, path, label):
  27. if parent_popup.has_node(label):
  28. var popup_node = parent_popup.get_node(label)
  29. var popup_menu = popup_node as PopupMenu
  30. assert(popup_menu)
  31. return popup_menu
  32. var popup_menu = PopupMenu.new()
  33. popup_menu.name = label
  34. popup_menu.hide_on_checkable_item_selection = false
  35. parent_popup.add_child(popup_menu)
  36. parent_popup.add_submenu_item(label, label)
  37. popup_menu.index_pressed.connect(_on_item_pressed.bind(popup_menu, path))
  38. return popup_menu
  39. func _on_item_pressed(item_index, popup_menu, path):
  40. var item_path = path + popup_menu.get_item_text(item_index)
  41. if popup_menu.is_item_radio_checkable(item_index):
  42. var checked = popup_menu.is_item_checked(item_index)
  43. if not checked:
  44. popup_menu.set_item_checked(item_index, true)
  45. for other_index in range(popup_menu.get_item_count()):
  46. if other_index != item_index:
  47. popup_menu.set_item_checked(other_index, false)
  48. emit_signal("option_selected", item_path)
  49. elif popup_menu.is_item_checkable(item_index):
  50. var checked = not popup_menu.is_item_checked(item_index)
  51. popup_menu.set_item_checked(item_index, checked)
  52. emit_signal("option_changed", item_path, checked)
  53. else:
  54. emit_signal("option_selected", item_path)