|
|
|
|
Reply From: |
domportera |
In C# I wrote something that can do this. It seems pretty simple to translate to GDScript if that’s more your jam. You can use it like this:
MultiLineButton button = new MultiLineButton("This button has multiple lines of text!");
AddChild(button.Control);
This is the MultiLineButton
class:
public class MultiLineButton
{
public MultiLineButton(string labelText, bool addVerticalPadding, bool autoWrap, bool maximizeAnchors)
{
Button = new Button();
ConfigureButtonControl(Button);
Label = new Label();
ConfigureLabel(Label, labelText, autoWrap, addVerticalPadding);
ConfigureLabelControl(label: Label, child: Button);
if (maximizeAnchors)
{
Button.MaximizeAnchors();
Label.MaximizeAnchors();
}
}
void ConfigureButtonControl(Control button)
{
button.SizeFlagsHorizontal = (int)Control.SizeFlags.ExpandFill;
button.SizeFlagsVertical = (int)Control.SizeFlags.ExpandFill;
button.ShowBehindParent = true;
}
void ConfigureLabelControl(Control label, Control child)
{
label.SizeFlagsHorizontal = (int)Control.SizeFlags.ExpandFill;
label.SizeFlagsVertical = (int)Control.SizeFlags.ExpandFill;
label.MouseFilter = Control.MouseFilterEnum.Ignore;
Label.AddChild(child);
}
protected static void ConfigureLabel(Label label, string text, bool autoWrap, bool addVerticalPadding)
{
label.Text = addVerticalPadding ? $"\n{text}\n" : text;
label.Autowrap = autoWrap;
label.Align = Godot.Label.AlignEnum.Center;
label.Valign = Godot.Label.VAlign.Center;
}
public Control Control => Label;
public Button Button { get; }
public Label Label { get; }
}
That MaximizeAnchors
function is just an extension method that does this:
public static void MaximizeAnchors(this Control control)
{
control.AnchorLeft = 0;
control.AnchorRight = 1;
control.AnchorTop = 0;
control.AnchorBottom = 1;
}
A generic version (that’s called in exactly the same way) that’s more future-proof to future child classes of Label is here. Not sure how this would be done in gdscript (some kind of duck typing stuff probably). but it provides an easy way to extend functionality and use your own Label classes or any that crop up in the future.
public class MultiLineButton : MultiLineButtonBase<Label>
{
public MultiLineButton(string labelText, bool addVerticalPadding, bool autoWrap = true, bool maximizeAnchors = true)
: base(labelText, addVerticalPadding, autoWrap, maximizeAnchors){ }
}
public class MultiLineButtonBase<T> where T : Label, new()
{
public MultiLineButtonBase(string labelText, bool addVerticalPadding, bool autoWrap, bool maximizeAnchors)
{
Button = new Button();
ConfigureButtonControl(Button);
Label = new T();
ConfigureLabel(Label, labelText, autoWrap, addVerticalPadding);
ConfigureLabelControl(label: Label, child: Button);
if (maximizeAnchors)
{
Button.MaximizeAnchors();
Label.MaximizeAnchors();
}
}
void ConfigureButtonControl(Control button)
{
button.SizeFlagsHorizontal = (int)Control.SizeFlags.ExpandFill;
button.SizeFlagsVertical = (int)Control.SizeFlags.ExpandFill;
button.ShowBehindParent = true;
}
void ConfigureLabelControl(Control label, Control child)
{
label.SizeFlagsHorizontal = (int)Control.SizeFlags.ExpandFill;
label.SizeFlagsVertical = (int)Control.SizeFlags.ExpandFill;
label.MouseFilter = Control.MouseFilterEnum.Ignore;
Label.AddChild(child);
}
protected static void ConfigureLabel(Label label, string text, bool autoWrap, bool addVerticalPadding)
{
label.Text = addVerticalPadding ? $"\n{text}\n" : text;
label.Autowrap = autoWrap;
label.Align = Godot.Label.AlignEnum.Center;
label.Valign = Godot.Label.VAlign.Center;
}
public Control Control => Label;
public Button Button { get; }
public Label Label { get; }
}