129 lines
4.2 KiB
GDScript

#Written:
#Date: 01/26/2019
#Author: Markus Septer
#Contributors: David Boucher, update to Godot 4, 10/17/2022
#How to use:
#1)If you already have "addons" folder in "res://", jump to step (3)
#2)If you don't have "addons" folder in "res://" create it
#3)Drag and drop the folder this script is (should be named "QuickPluginMaker") in into "res://addons"
#Folder structure should look like this: "res://addons/QuickPluginManager"
#NB:if you wish to change name of this plugin through godot editor you also have to change var "PLUGIN_SELF_NAME" to same name
@tool
extends EditorPlugin
const PLUGIN_PATH = "res://addons"
const POPUP_BUTTON_TEXT = "Manage Plugins"
const MENU_BUTTON_TOOLTIP = "Quickly enable/disable plugins"
#if you change name of plugin from godot editor this variable also must changed to same
const PLUGIN_SELF_NAME = "QuickPluginManager"
var _plugin_menu_btn = MenuButton.new()
var _plugins_menu = _plugin_menu_btn.get_popup()
var _plugins_data = {}
var _menu_items_idx = 0
func _enter_tree():
_plugin_menu_btn.text = POPUP_BUTTON_TEXT
_plugin_menu_btn.tooltip_text = MENU_BUTTON_TOOLTIP
_populate_menu()
_plugins_menu.index_pressed.connect(_item_toggled.bind(_plugins_menu))
_plugin_menu_btn.about_to_popup.connect(_menu_popup_about_to_show)
add_control_to_container(EditorPlugin.CONTAINER_TOOLBAR, _plugin_menu_btn)
func _exit_tree():
remove_control_from_container(EditorPlugin.CONTAINER_TOOLBAR, _plugin_menu_btn)
if _plugin_menu_btn:
_plugin_menu_btn.queue_free()
func _item_toggled(item_index, menuObj):
var is_item_checked = menuObj.is_item_checked(item_index)
_plugins_menu.set_item_checked(item_index, not is_item_checked)
for plugin_name in _plugins_data:
var plugin_info = _plugins_data[plugin_name]
if item_index == plugin_info.menu_item_index:
var plugin_folder_name = plugin_info.plugin_folder
get_editor_interface().set_plugin_enabled(plugin_folder_name, not is_item_checked)
func _refresh_plugins_menu_list():
_plugins_menu.clear()
_menu_items_idx = 0
_plugins_data.clear()
_populate_menu()
func _populate_menu():
#Get list of addons directories
var addons_list: Array = []
addons_list = get_list_directories_name_at("res://addons/")
#print list of addons name
# for a in addons_list:
# print(a)
#Get files path of each addon .cfg
if addons_list != null:
for addon_name in addons_list:
var addon_cfg_path: Array = []
addon_cfg_path = get_list_path_of_files_with_ext("res://addons/"+addon_name+"/", ".cfg")
if addon_cfg_path != null:
#If more than one cfg file exist, only keep plugin.cfg
if addon_cfg_path.size() > 1:
var idx = 0
for cfg in addon_cfg_path:
if cfg.right(10) != "plugin.cfg":
addon_cfg_path.remove_at(idx)
idx += 1
if addon_cfg_path != null and addon_cfg_path.size() > 0:
# print(addon_cfg_path)
#Add addon to _plugins_menu
var conf = ConfigFile.new()
conf.load(addon_cfg_path[0]) #take the first .cfg file found in each addon directory
var plugin_name = str(conf.get_value("plugin", "name"))
var plugin_info = { "plugin_folder":addon_name, "menu_item_index":_menu_items_idx }
var isPluginEnabled = get_editor_interface().is_plugin_enabled(addon_name)
if plugin_name != PLUGIN_SELF_NAME:
_plugins_menu.add_check_item(plugin_name)
_plugins_menu.set_item_checked(_menu_items_idx, isPluginEnabled)
_plugins_data[plugin_name] = plugin_info
_menu_items_idx += 1
#no need to increment "_menu_items_idx" as we already did it above
#add plugin itself as last item to menu
_plugins_menu.add_check_item(PLUGIN_SELF_NAME)
_plugins_menu.set_item_checked(_menu_items_idx, get_editor_interface().is_plugin_enabled(PLUGIN_SELF_NAME))
_plugins_menu.set_item_disabled(_menu_items_idx, true)
else:
print("An error occurred when trying to access the path.")
func _menu_popup_about_to_show():
_refresh_plugins_menu_list()
func get_list_path_of_files_with_ext(path: String, ext: String):
var path_array: Array = []
for file in DirAccess.get_files_at(path):
if file.ends_with(ext):
path_array.append(path+file)
return path_array
func get_list_directories_name_at(path: String):
var path_array: Array = []
for dir in DirAccess.get_directories_at(path):
path_array.append(dir)
return path_array