diff --git a/CHANGELOG.md b/CHANGELOG.md index 19b2844..5f834c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ Additions - Added UiControls.NavType, which stores the most recently used type of ui navigation - Added SetWidthBasedOnAspect and SetHeightBasedOnAspect to images - Added the ability to set a custom SamplerState for images +- Added some useful additional constructors to various elements Improvements - Allow scrolling panels to contain other scrolling panels diff --git a/MLEM.Ui/Elements/Button.cs b/MLEM.Ui/Elements/Button.cs index a5c3425..bd74f49 100644 --- a/MLEM.Ui/Elements/Button.cs +++ b/MLEM.Ui/Elements/Button.cs @@ -87,6 +87,13 @@ namespace MLEM.Ui.Elements { private bool isDisabled; + /// + /// Creates a new button with the given settings and no text or tooltip. + /// + /// The button's anchor + /// The button's size + public Button(Anchor anchor, Vector2 size) : base(anchor, size) {} + /// /// Creates a new button with the given settings /// @@ -94,7 +101,7 @@ namespace MLEM.Ui.Elements { /// The button's size /// The text that should be displayed on the button /// The text that should be displayed in a when hovering over this button - public Button(Anchor anchor, Vector2 size, string text = null, string tooltipText = null) : base(anchor, size) { + public Button(Anchor anchor, Vector2 size, string text = null, string tooltipText = null) : this(anchor, size) { if (text != null) { this.Text = new Paragraph(Anchor.Center, 1, text, true); this.Text.Padding = this.Text.Padding.OrStyle(new Padding(1), 1); @@ -104,6 +111,23 @@ namespace MLEM.Ui.Elements { this.Tooltip = this.AddTooltip(tooltipText); } + /// + /// Creates a new button with the given settings + /// + /// The button's anchor + /// The button's size + /// The text that should be displayed on the button + /// The text that should be displayed in a when hovering over this button + public Button(Anchor anchor, Vector2 size, Paragraph.TextCallback textCallback = null, Paragraph.TextCallback tooltipTextCallback = null) : this(anchor, size) { + if (textCallback != null) { + this.Text = new Paragraph(Anchor.Center, 1, textCallback, true); + this.Text.Padding = this.Text.Padding.OrStyle(new Padding(1), 1); + this.AddChild(this.Text); + } + if (tooltipTextCallback != null) + this.Tooltip = this.AddTooltip(tooltipTextCallback); + } + /// public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) { var tex = this.Texture; diff --git a/MLEM.Ui/Elements/Dropdown.cs b/MLEM.Ui/Elements/Dropdown.cs index 4299035..1131494 100644 --- a/MLEM.Ui/Elements/Dropdown.cs +++ b/MLEM.Ui/Elements/Dropdown.cs @@ -12,8 +12,7 @@ namespace MLEM.Ui.Elements { /// /// The panel that this dropdown contains. It will be displayed upon pressing the dropdown button. /// - public readonly Panel Panel; - + public Panel Panel { get; private set; } /// /// This property stores whether the dropdown is currently opened or not /// @@ -29,6 +28,18 @@ namespace MLEM.Ui.Elements { /// public GenericCallback OnOpenedOrClosed; + /// + /// Creates a new dropdown with the given settings and no text or tooltip. + /// + /// The dropdown's anchor + /// The dropdown button's size + /// The height of the . If this is 0, the panel will be set to . + /// Whether this dropdown's should automatically add a scroll bar to scroll towards elements that are beyond the area it covers. + /// Whether this dropdown's 's scroll bar should be hidden automatically if the panel does not contain enough children to allow for scrolling. This only has an effect if is . + public Dropdown(Anchor anchor, Vector2 size, float panelHeight = 0, bool scrollPanel = false, bool autoHidePanelScrollbar = true) : base(anchor, size) { + this.Initialize(panelHeight, scrollPanel, autoHidePanelScrollbar); + } + /// /// Creates a new dropdown with the given settings /// @@ -40,30 +51,21 @@ namespace MLEM.Ui.Elements { /// Whether this dropdown's should automatically add a scroll bar to scroll towards elements that are beyond the area it covers. /// Whether this dropdown's 's scroll bar should be hidden automatically if the panel does not contain enough children to allow for scrolling. This only has an effect if is . public Dropdown(Anchor anchor, Vector2 size, string text = null, string tooltipText = null, float panelHeight = 0, bool scrollPanel = false, bool autoHidePanelScrollbar = true) : base(anchor, size, text, tooltipText) { - this.Panel = this.AddChild(new Panel(Anchor.TopCenter, Vector2.Zero, Vector2.Zero, panelHeight == 0, scrollPanel, autoHidePanelScrollbar) { - IsHidden = true - }); - this.OnAreaUpdated += e => { - this.Panel.Size = new Vector2(e.Area.Width / e.Scale, panelHeight); - this.Panel.PositionOffset = new Vector2(0, e.Area.Height / e.Scale); - }; - this.OnOpenedOrClosed += e => this.Priority = this.IsOpen ? 10000 : 0; - this.OnPressed += e => { - this.IsOpen = !this.IsOpen; - // close other dropdowns in the same root when we open - if (this.IsOpen) { - this.Root.Element.AndChildren(o => { - if (o != this && o is Dropdown d && d.IsOpen) - d.IsOpen = false; - }); - } - }; - this.GetGamepadNextElement = (dir, usualNext) => { - // Force navigate down to our first child if we're open - if (this.IsOpen && dir == Direction2.Down) - return this.Panel.GetChildren().FirstOrDefault(c => c.CanBeSelected) ?? usualNext; - return usualNext; - }; + this.Initialize(panelHeight, scrollPanel, autoHidePanelScrollbar); + } + + /// + /// Creates a new dropdown with the given settings + /// + /// The dropdown's anchor + /// The dropdown button's size + /// The text displayed on the dropdown button + /// The text displayed as a tooltip when hovering over the dropdown button + /// The height of the . If this is 0, the panel will be set to . + /// Whether this dropdown's should automatically add a scroll bar to scroll towards elements that are beyond the area it covers. + /// Whether this dropdown's 's scroll bar should be hidden automatically if the panel does not contain enough children to allow for scrolling. This only has an effect if is . + public Dropdown(Anchor anchor, Vector2 size, Paragraph.TextCallback textCallback = null, Paragraph.TextCallback tooltipTextCallback = null, float panelHeight = 0, bool scrollPanel = false, bool autoHidePanelScrollbar = true) : base(anchor, size, textCallback, tooltipTextCallback) { + this.Initialize(panelHeight, scrollPanel, autoHidePanelScrollbar); } /// @@ -119,5 +121,32 @@ namespace MLEM.Ui.Elements { return paragraph; } + private void Initialize(float panelHeight, bool scrollPanel, bool autoHidePanelScrollbar) { + this.Panel = this.AddChild(new Panel(Anchor.TopCenter, Vector2.Zero, panelHeight == 0, scrollPanel, autoHidePanelScrollbar) { + IsHidden = true + }); + this.OnAreaUpdated += e => { + this.Panel.Size = new Vector2(e.Area.Width / e.Scale, panelHeight); + this.Panel.PositionOffset = new Vector2(0, e.Area.Height / e.Scale); + }; + this.OnOpenedOrClosed += e => this.Priority = this.IsOpen ? 10000 : 0; + this.OnPressed += e => { + this.IsOpen = !this.IsOpen; + // close other dropdowns in the same root when we open + if (this.IsOpen) { + this.Root.Element.AndChildren(o => { + if (o != this && o is Dropdown d && d.IsOpen) + d.IsOpen = false; + }); + } + }; + this.GetGamepadNextElement = (dir, usualNext) => { + // Force navigate down to our first child if we're open + if (this.IsOpen && dir == Direction2.Down) + return this.Panel.GetChildren().FirstOrDefault(c => c.CanBeSelected) ?? usualNext; + return usualNext; + }; + } + } } diff --git a/MLEM.Ui/Elements/Group.cs b/MLEM.Ui/Elements/Group.cs index de6f1a9..ca3a9ad 100644 --- a/MLEM.Ui/Elements/Group.cs +++ b/MLEM.Ui/Elements/Group.cs @@ -14,8 +14,18 @@ namespace MLEM.Ui.Elements { /// /// The group's anchor /// The group's size - /// Whether the group's height should be based on its children's height - public Group(Anchor anchor, Vector2 size, bool setHeightBasedOnChildren = true) : base(anchor, size) { + /// Whether the group's height should be based on its children's height, see . + public Group(Anchor anchor, Vector2 size, bool setHeightBasedOnChildren = true) : this(anchor, size, false, setHeightBasedOnChildren) {} + + /// + /// Creates a new group with the given settings + /// + /// The group's anchor + /// The group's size + /// Whether the group's width should be based on its children's width, see . + /// Whether the group's height should be based on its children's height, see . + public Group(Anchor anchor, Vector2 size, bool setWidthBasedOnChildren, bool setHeightBasedOnChildren) : base(anchor, size) { + this.SetWidthBasedOnChildren = setWidthBasedOnChildren; this.SetHeightBasedOnChildren = setHeightBasedOnChildren; this.CanBeSelected = false; } diff --git a/MLEM.Ui/Elements/Panel.cs b/MLEM.Ui/Elements/Panel.cs index 585dc9a..65b974f 100644 --- a/MLEM.Ui/Elements/Panel.cs +++ b/MLEM.Ui/Elements/Panel.cs @@ -104,6 +104,16 @@ namespace MLEM.Ui.Elements { } } + /// + /// Creates a new panel with the given settings. + /// + /// The panel's anchor + /// The panel's default size + /// Whether the panel should automatically calculate its height based on its children's size + /// Whether this panel should automatically add a scroll bar to scroll towards elements that are beyond the area this panel covers + /// Whether the scroll bar should be hidden automatically if the panel does not contain enough children to allow for scrolling. This only has an effect if is . + public Panel(Anchor anchor, Vector2 size, bool setHeightBasedOnChildren = false, bool scrollOverflow = false, bool autoHideScrollbar = true) : this(anchor, size, Vector2.Zero, setHeightBasedOnChildren, scrollOverflow, autoHideScrollbar) {} + /// public override void ForceUpdateArea() { if (this.scrollOverflow) { diff --git a/MLEM.Ui/Elements/Paragraph.cs b/MLEM.Ui/Elements/Paragraph.cs index c508fa0..3560f56 100644 --- a/MLEM.Ui/Elements/Paragraph.cs +++ b/MLEM.Ui/Elements/Paragraph.cs @@ -166,6 +166,30 @@ namespace MLEM.Ui.Elements { private float textScaleMultiplier = 1; private bool autoAdjustWidth; + /// + /// Creates a new paragraph with the given settings. + /// + /// The paragraph's anchor + /// The paragraph's width. Note that its height is automatically calculated. + /// The paragraph's text + /// The paragraph's text alignment. + /// Whether the paragraph's width should automatically be calculated based on the text within it. + public Paragraph(Anchor anchor, float width, TextCallback textCallback, TextAlignment alignment, bool autoAdjustWidth = false) : this(anchor, width, textCallback, autoAdjustWidth) { + this.Alignment = alignment; + } + + /// + /// Creates a new paragraph with the given settings. + /// + /// The paragraph's anchor + /// The paragraph's width. Note that its height is automatically calculated. + /// The paragraph's text + /// The paragraph's text alignment. + /// Whether the paragraph's width should automatically be calculated based on the text within it. + public Paragraph(Anchor anchor, float width, string text, TextAlignment alignment, bool autoAdjustWidth = false) : this(anchor, width, text, autoAdjustWidth) { + this.Alignment = alignment; + } + /// /// Creates a new paragraph with the given settings. /// @@ -177,7 +201,13 @@ namespace MLEM.Ui.Elements { this.GetTextCallback = textCallback; } - /// + /// + /// Creates a new paragraph with the given settings. + /// + /// The paragraph's anchor + /// The paragraph's width. Note that its height is automatically calculated. + /// The paragraph's text + /// Whether the paragraph's width should automatically be calculated based on the text within it. public Paragraph(Anchor anchor, float width, string text, bool autoAdjustWidth = false) : base(anchor, new Vector2(width, 0)) { this.Text = text; this.AutoAdjustWidth = autoAdjustWidth;