-
-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathmenu.gd
More file actions
152 lines (117 loc) · 5.65 KB
/
menu.gd
File metadata and controls
152 lines (117 loc) · 5.65 KB
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
## This module handles adding a menu to the script editor with formatter commands.
## It safely locates the script editor's menu bar and adds our custom menu.
@tool
extends Node
signal menu_item_selected(command: String)
const MENU_TEXT = "Format"
const MENU_ITEMS = {
"format_script": "Format Current Script",
"lint_script": "Lint Current Script",
"reorder_code": "Reorder Code",
"install_update": "Install or Update Formatter",
"manual_install": "Install Formatter Manually",
"uninstall": "Uninstall Formatter",
"report_issue": "Report Issue",
"help": "Help",
}
var menu_button: MenuButton = null
var popup_menu: PopupMenu = null
func _ready() -> void:
# At the start we insert the menu in the script editor
var script_editor := EditorInterface.get_script_editor()
var last_menu_button := _find_last_menu_button(script_editor)
if not is_instance_valid(last_menu_button):
push_warning("GDScript Formatter: Could not find valid menu button in script editor. Menu will not be available. Use the command palette instead.")
return
menu_button = MenuButton.new()
menu_button.text = MENU_TEXT
menu_button.flat = true
popup_menu = menu_button.get_popup()
_populate_menu()
popup_menu.id_pressed.connect(_on_menu_item_pressed)
last_menu_button.add_sibling(menu_button)
## Cleans up the menu from the script editor. Call this when disabling the
## plugin (in _exit_tree()).
func remove_formatter_menu() -> void:
if is_instance_valid(menu_button):
if is_instance_valid(popup_menu):
popup_menu.id_pressed.disconnect(_on_menu_item_pressed)
menu_button.queue_free()
menu_button = null
popup_menu = null
func update_menu(show_uninstall: bool) -> void:
if not is_instance_valid(popup_menu):
return
popup_menu.clear()
_populate_menu(show_uninstall)
## Searches for and returns the last menu node in the script editor top menu bar,
## or null if not found.
func _find_last_menu_button(script_editor: Control) -> MenuButton:
# The first child of the script editor should be a VBoxContainer (main container for the script editor main screen)
# Then the first child of that container should be an HBoxContainer (the menu bar)
# This is based on the current structure of Godot's script editor as of Godot 4.5
# Note: We add multiple checks in there with null returns mainly in case something changes in a future
if script_editor.get_child_count() == 0:
return null
var main_container := script_editor.get_child(0)
if not is_instance_valid(main_container) or not main_container is VBoxContainer:
return null
if main_container.get_child_count() == 0:
return null
var menu_bar := main_container.get_child(0)
if not is_instance_valid(menu_bar) or not menu_bar is HBoxContainer:
return null
# We reached the menu bar. So now we loop through all the children look for
# the last menu button, which would be the last menu in the menu list.
# Note: Here the goal is to insert the menu after the debug menu, but we
# don't check for the button text because "debug" would only work in English
# this should work in any language.
var last_menu_button: MenuButton = null
for child in menu_bar.get_children():
if child is MenuButton:
last_menu_button = child as MenuButton
return last_menu_button
func _populate_menu(show_uninstall: bool = true) -> void:
if not is_instance_valid(popup_menu):
return
var current_item_index := 0
popup_menu.add_item(MENU_ITEMS["format_script"], current_item_index)
popup_menu.set_item_metadata(current_item_index, "format_script")
popup_menu.set_item_tooltip(current_item_index, "Run the GDScript Formatter over the current script")
current_item_index += 1
popup_menu.add_item(MENU_ITEMS["lint_script"], current_item_index)
popup_menu.set_item_metadata(current_item_index, "lint_script")
popup_menu.set_item_tooltip(current_item_index, "Check the current script for linting issues")
current_item_index += 1
popup_menu.add_item(MENU_ITEMS["reorder_code"], current_item_index)
popup_menu.set_item_metadata(current_item_index, "reorder_code")
popup_menu.set_item_tooltip(current_item_index, "Reorder the code elements in the current script according to the GDScript Style Guide")
current_item_index += 1
popup_menu.add_separator()
popup_menu.add_item(MENU_ITEMS["install_update"], current_item_index)
popup_menu.set_item_metadata(current_item_index, "install_update")
popup_menu.set_item_tooltip(current_item_index, "Download the latest version of the GDScript Formatter")
current_item_index += 1
popup_menu.add_item(MENU_ITEMS["manual_install"], current_item_index)
popup_menu.set_item_metadata(current_item_index, "manual_install")
popup_menu.set_item_tooltip(current_item_index, "Manually install GDScript Formatter")
current_item_index += 1
if show_uninstall:
popup_menu.add_item(MENU_ITEMS["uninstall"], current_item_index)
popup_menu.set_item_metadata(current_item_index, "uninstall")
popup_menu.set_item_tooltip(current_item_index, "Remove the GDScript Formatter installed through this add-on from your computer")
current_item_index += 1
popup_menu.add_separator()
popup_menu.add_item(MENU_ITEMS["report_issue"], current_item_index)
popup_menu.set_item_metadata(current_item_index, "report_issue")
popup_menu.set_item_tooltip(current_item_index, "Tell us about problems or bugs you found")
current_item_index += 1
popup_menu.add_item(MENU_ITEMS["help"], current_item_index)
popup_menu.set_item_metadata(current_item_index, "help")
popup_menu.set_item_tooltip(current_item_index, "Learn how to use the GDScript Formatter")
func _on_menu_item_pressed(id: int) -> void:
if not is_instance_valid(popup_menu):
return
var command: String = popup_menu.get_item_metadata(id)
if not command.is_empty():
menu_item_selected.emit(command)