221 lines
7.4 KiB
GDScript
221 lines
7.4 KiB
GDScript
@tool
|
||
extends EditorPlugin
|
||
|
||
var base:Control
|
||
var editor_settings:EditorSettings
|
||
|
||
const TOOL = preload("res://addons/cba/tool.tscn")
|
||
var settings:Dictionary = {}
|
||
var bg:TextureRect
|
||
var tool:Window
|
||
var theme:Theme
|
||
|
||
var accent_color:Color
|
||
|
||
func _disable_plugin():
|
||
bg.queue_free()
|
||
editor_settings.set("interface/theme/custom_theme", "")
|
||
editor_settings.set("interface/theme/preset", "Default")
|
||
remove_tool_menu_item("Backgrounds")
|
||
|
||
func _enter_tree():
|
||
#Benchmark.start("init")
|
||
if not Engine.is_editor_hint(): return
|
||
|
||
base = EditorInterface.get_base_control()
|
||
editor_settings = EditorInterface.get_editor_settings()
|
||
editor_settings.settings_changed.connect(func():
|
||
for setting in editor_settings.get_changed_settings():
|
||
_setting_changed(setting)
|
||
)
|
||
bg = TextureRect.new()
|
||
bg.name = "Editor Background"
|
||
bg.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
bg.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||
bg.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||
base.add_child.call_deferred(bg)
|
||
# move it to the top of the tree so it's behind all the UI
|
||
base.move_child.call_deferred(bg, 0)
|
||
await bg.ready
|
||
|
||
theme = preload("res://addons/cba/theme.tres")
|
||
if editor_settings.get("interface/theme/custom_theme") != "res://addons/cba/theme.tres":
|
||
editor_settings.set("interface/theme/custom_theme", "res://addons/cba/theme.tres")
|
||
if editor_settings.get("interface/theme/preset") != "Custom":
|
||
editor_settings.set("interface/theme/preset", "Custom")
|
||
|
||
await base.get_tree().physics_frame
|
||
load_settings()
|
||
|
||
add_tool_menu_item("Backgrounds", func():
|
||
if is_instance_valid(tool): printerr("There is already a background picker window open."); return
|
||
tool = TOOL.instantiate()
|
||
tool.main = self
|
||
base.add_child(tool)
|
||
tool.start()
|
||
tool.popup_centered()
|
||
)
|
||
#Benchmark.end("init")
|
||
|
||
func change_setting(value:Variant, setting:String, update_ui:bool = false, update_setting:bool = true):
|
||
var is_prev_ready := is_instance_valid(tool)
|
||
match setting:
|
||
"image":
|
||
var img := load_image(value)
|
||
if is_prev_ready: tool.preview.texture = img
|
||
if update_setting: bg.texture = img
|
||
"stretch":
|
||
if update_setting: bg.stretch_mode = value
|
||
if is_prev_ready:
|
||
tool.preview.stretch_mode = value
|
||
if update_ui:
|
||
tool.get_node("VBoxContainer/HBoxContainer/VBoxContainer/stretch mode").select(value)
|
||
"filter":
|
||
if update_setting: bg.texture_filter = value
|
||
if is_prev_ready:
|
||
tool.preview.texture_filter = value
|
||
if update_ui:
|
||
tool.get_node("VBoxContainer/HBoxContainer/VBoxContainer/filter mode").select(value)
|
||
"ui_color":
|
||
if is_prev_ready:
|
||
if update_ui:
|
||
value = Color(settings["ui_color"])
|
||
tool.get_node("VBoxContainer/HBoxContainer/VBoxContainer2/ui_color").color = value
|
||
else:
|
||
value = tool.get_node("VBoxContainer/HBoxContainer/VBoxContainer2/ui_color").color
|
||
if not update_ui && update_setting:
|
||
if value == Color(settings["ui_color"]): return
|
||
change_theme_color(value)
|
||
settings["ui_color"] = value.to_html()
|
||
value = null
|
||
"bg_modulate":
|
||
if value is String: value = Color(value)
|
||
if update_setting: bg.modulate = value
|
||
if is_prev_ready:
|
||
tool.preview.modulate = value
|
||
if update_ui:
|
||
tool.get_node("VBoxContainer/HBoxContainer/VBoxContainer2/bg_modulate").color = value
|
||
value = value.to_html()
|
||
"edit_transparency":
|
||
if is_prev_ready:
|
||
if update_ui:
|
||
value = settings["edit_transparency"]
|
||
tool.get_node("VBoxContainer/edit_transparency").button_pressed = value
|
||
else:
|
||
value = tool.get_node("VBoxContainer/edit_transparency").button_pressed
|
||
if not update_ui && update_setting:
|
||
if value == settings["edit_transparency"]: return
|
||
settings["edit_transparency"] = value
|
||
change_theme_color(Color(settings["ui_color"]))
|
||
value = null
|
||
if value != null: settings[setting] = value
|
||
|
||
func load_image(path:String) -> Texture2D:
|
||
var file := FileAccess.open(path, FileAccess.READ)
|
||
if file == null: printerr("file not found: ", path); return
|
||
var image = Image.load_from_file(path)
|
||
var out = ImageTexture.create_from_image(image)
|
||
return out
|
||
|
||
func load_settings():
|
||
if FileAccess.file_exists("res://addons/cba/config.json"):
|
||
var file := FileAccess.open("res://addons/cba/config.json", FileAccess.READ)
|
||
if file == null:
|
||
file = FileAccess.open("res://addons/cba/config.json", FileAccess.WRITE_READ)
|
||
assert(file != null, "Error opening file.")
|
||
return
|
||
else:
|
||
settings = JSON.parse_string(file.get_as_text())
|
||
file.close()
|
||
else:
|
||
var file := FileAccess.open("res://addons/cba/config.json", FileAccess.WRITE)
|
||
var defaults := {
|
||
"filter": 0.0,
|
||
"image": ProjectSettings.globalize_path("res://addons/cba/images/default.png"),
|
||
"stretch": 1,
|
||
"ui_color": "00000088",
|
||
"bg_modulate": "ffffffb0",
|
||
"edit_transparency": false,
|
||
}
|
||
file.store_string(JSON.stringify(defaults, "\t"))
|
||
settings = defaults
|
||
file.close()
|
||
for s in settings.keys():
|
||
change_setting(settings[s], s, true)
|
||
|
||
func save_settings():
|
||
var file := FileAccess.open("res://addons/cba/config.json", FileAccess.WRITE)
|
||
file.store_string(JSON.stringify(settings, "\t"))
|
||
|
||
func _setting_changed(setting:String):
|
||
match setting:
|
||
"interface/theme/accent_color":
|
||
change_theme_color(Color(settings["ui_color"]))
|
||
|
||
func change_theme_color(col:Color):
|
||
#Benchmark.start("change theme color")
|
||
|
||
accent_color = editor_settings.get_setting("interface/theme/accent_color")
|
||
|
||
var controls_list = get_all_controls([base])
|
||
|
||
var col2 := Color(col, col.a/2.0)
|
||
var col3 := Color(col, min(col.a/col.v, col.a/4.0))
|
||
change_color("EditorStyles", "Background", col)
|
||
change_color("EditorStyles", "BottomPanel", col)
|
||
change_color("EditorStyles", "BottomPanelDebuggerOverride", col)
|
||
change_color("EditorStyles", "Content", col)
|
||
change_color("EditorStyles", "LaunchPadNormal", col)
|
||
|
||
change_color("TabContainer", "panel", col)
|
||
change_color("TabContainer", "tab_selected", col, accent_color)
|
||
change_color("TabContainer", "tab_unselected", col2)
|
||
change_color("TabContainer", "tab_hovered", col2)
|
||
|
||
change_color("TabBar", "tab_selected", col, accent_color)
|
||
change_color("TabBar", "tab_unselected", col2)
|
||
change_color("TabBar", "tab_hovered", col2)
|
||
|
||
change_color("TabContainerOdd", "tab_selected", col, accent_color)
|
||
change_color("TabContainerOdd", "panel", col2)
|
||
|
||
# bordered
|
||
change_color("Button", "normal", col3)
|
||
change_color("MenuButton", "normal", col3)
|
||
change_color("OptionButton", "normal", col3)
|
||
change_color("RichTextLabel", "normal", col3)
|
||
change_color("LineEdit", "normal", col3)
|
||
change_color("TextEdit", "normal", col3)
|
||
change_color("LineEdit", "read_only", col3)
|
||
change_color("TextEdit", "read_only", col3)
|
||
change_color("EditorProperty", "child_bg", col3)
|
||
|
||
change_color("EditorInspectorCategory", "bg", col2)
|
||
|
||
# fix to old values showing up in transparent preview
|
||
if settings["edit_transparency"]:
|
||
change_color("LineEdit", "focus", col3)
|
||
else:
|
||
change_color("LineEdit", "focus", Color.BLACK)
|
||
|
||
# trigger an update
|
||
theme.get_stylebox("Background", "EditorStyles").emit_changed()
|
||
|
||
#Benchmark.end("change theme color")
|
||
|
||
func get_all_controls(nodes:Array[Node]) -> Array[Node]:
|
||
var out:Array[Node] = []
|
||
for node in nodes:
|
||
if node is Control: out.append(node)
|
||
var children := node.get_children() as Array[Node]
|
||
out += get_all_controls(children)
|
||
return out
|
||
|
||
func change_color(type:String, name:String, col:Color, border = null):
|
||
var box:StyleBoxFlat = theme.get_stylebox(name, type)
|
||
box.set_block_signals(true)
|
||
box.bg_color = col
|
||
if border != null:
|
||
box.border_color = border
|
||
box.set_block_signals(false)
|