I am working on something in which I want to override the Control’s _make_custom_tooltip function, I know you can do this by assigning a script to the object and then override it there. But I was wondering if I could do it like you can with a node’s properties like;
You could create a generic script that overrides things for you. For example I’m working on an InteractionComponent3D that has a custom_highlight_material exported variable. If it’s left blank it does nothing. If I drag a material into it, whenever the object is highlighted by the player it uses that shader instead of the default.
In the same way you could add an exported boolean say. Then your script would look like:
@export var has_custom_tooltip = false
_ready() -> void
if has_custom_tooltip:
self.tooltip_text = _make_custom_tooltip()
You could also create an ENUM and match/case on it. It’s not as elegant as the solution you want, but it works.
I mean, it’s technically possible in a totally hacky way that will break stuff for sure… It’s kinda a poor man trait system
extends Node
const SCRIPT = """
extends {{extend_class}}
var make_custom_tooltip_callable:Callable
func _make_custom_tooltip(str):
if make_custom_tooltip_callable:
return make_custom_tooltip_callable.call(str)
return null
"""
func _ready() -> void:
for child in get_children():
if child is Control:
# Get the node's script
var scr = child.get_script()
var cls = ""
if scr is GDScript:
# extend that class
cls = '"%s"' % scr.resource_path
else:
# hope it's not a C# or GDExtension script and get the base class of the node
cls = child.get_class()
# Create a new script
scr = GDScript.new()
# Set its source code with the correct class
scr.source_code = SCRIPT.format({extend_class = cls}, "{{_}}")
# Reload implementation
scr.reload()
# And set the new script to the child
child.set_script(scr)
# Now we can "override" that
child.make_custom_tooltip_callable = func(str):
var hbox = HBoxContainer.new()
var tex = TextureRect.new()
var lbl = Label.new()
tex.texture = preload("res://icon.svg")
tex.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
tex.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
tex.custom_minimum_size = Vector2(32, 32)
lbl.text = "CUSTOM %s" % str
hbox.add_child(tex)
hbox.add_child(lbl)
return hbox
Result:
The right ColorRect had already an script attached.