加两个插件
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
## 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",
|
||||
"update": "Update 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.switch_on_hover = true
|
||||
menu_button.flat = false
|
||||
menu_button.theme_type_variation = &"FlatMenuButton"
|
||||
|
||||
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() -> void:
|
||||
if not is_instance_valid(popup_menu):
|
||||
return
|
||||
popup_menu.clear()
|
||||
_populate_menu()
|
||||
|
||||
|
||||
## 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() -> 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")
|
||||
|
||||
popup_menu.add_separator()
|
||||
|
||||
# NOTE: When we add separators, it bumps the internal index of menu items.
|
||||
# That's why we have to increase it even on separators. Otherwise the
|
||||
# tooltip will lose sync.
|
||||
current_item_index += 2
|
||||
popup_menu.add_item(MENU_ITEMS["update"], current_item_index)
|
||||
popup_menu.set_item_metadata(current_item_index, "update")
|
||||
popup_menu.set_item_tooltip(current_item_index, "Download the latest version of the GDScript Formatter")
|
||||
|
||||
popup_menu.add_separator()
|
||||
|
||||
# Bumped index by 1 extra step because of the previous separator.
|
||||
current_item_index += 2
|
||||
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)
|
||||
Reference in New Issue
Block a user