2019-08-24 12:40:20 +02:00
using Microsoft.Xna.Framework ;
using MLEM.Input ;
2019-08-27 21:44:02 +02:00
using MLEM.Textures ;
2019-08-24 12:40:20 +02:00
namespace MLEM.Ui.Elements {
2020-05-22 17:02:24 +02:00
/// <summary>
/// This class contains a set of helper methods that aid in creating special kinds of compound <see cref="Element"/> types for use inside of a <see cref="UiSystem"/>.
/// </summary>
2019-08-24 12:40:20 +02:00
public static class ElementHelper {
2020-05-22 17:02:24 +02:00
/// <summary>
/// Creates a button with an image on the left side of its text.
/// </summary>
/// <param name="anchor">The button's anchor</param>
/// <param name="size">The button's size</param>
/// <param name="texture">The texture of the image to render on the button</param>
/// <param name="text">The text to display on the button</param>
/// <param name="tooltipText">The text of the button's tooltip</param>
/// <param name="tooltipWidth">The width of the button's tooltip</param>
/// <param name="imagePadding">The <see cref="Element.Padding"/> of the button's image</param>
/// <returns>An image button</returns>
2019-09-26 22:16:21 +02:00
public static Button ImageButton ( Anchor anchor , Vector2 size , TextureRegion texture , string text = null , string tooltipText = null , float tooltipWidth = 50 , float imagePadding = 2 ) {
2019-08-27 21:44:02 +02:00
var button = new Button ( anchor , size , text , tooltipText , tooltipWidth ) ;
2019-09-26 22:16:21 +02:00
var image = new Image ( Anchor . CenterLeft , Vector2 . One , texture ) { Padding = new Vector2 ( imagePadding ) } ;
2019-08-27 21:44:02 +02:00
button . OnAreaUpdated + = e = > image . Size = new Vector2 ( e . Area . Height , e . Area . Height ) / e . Scale ;
button . AddChild ( image , 0 ) ;
return button ;
}
2020-05-22 17:02:24 +02:00
/// <summary>
/// Creates a panel that contains a paragraph of text and a button to close the panel.
/// The panel is part of a group, which causes elements in the background (behind and around the panel) to not be clickable, leaving only the "close" button.
/// </summary>
/// <param name="system">The ui system to add the panel to, optional.</param>
/// <param name="anchor">The anchor of the panel</param>
/// <param name="width">The width of the panel</param>
/// <param name="text">The text to display on the panel</param>
/// <param name="buttonHeight">The height of the "close" button</param>
/// <param name="okText">The text on the "close" button</param>
/// <returns>An info box panel</returns>
2019-08-24 15:00:08 +02:00
public static Panel ShowInfoBox ( UiSystem system , Anchor anchor , float width , string text , float buttonHeight = 10 , string okText = "Okay" ) {
2019-12-25 19:16:07 +01:00
var group = new Group ( Anchor . TopLeft , Vector2 . One , false ) ;
var box = group . AddChild ( new Panel ( anchor , new Vector2 ( width , 1 ) , Vector2 . Zero , true ) ) ;
2019-08-24 15:00:08 +02:00
box . AddChild ( new Paragraph ( Anchor . AutoLeft , 1 , text ) ) ;
2019-09-09 17:12:36 +02:00
var button = box . AddChild ( new Button ( Anchor . AutoCenter , new Vector2 ( 0.5F , buttonHeight ) , okText ) {
2019-08-25 21:49:27 +02:00
OnPressed = element = > system . Remove ( "InfoBox" ) ,
2019-08-24 15:00:08 +02:00
PositionOffset = new Vector2 ( 0 , 1 )
} ) ;
2019-12-25 19:16:07 +01:00
var root = system . Add ( "InfoBox" , group ) ;
2019-09-09 17:12:36 +02:00
root . SelectElement ( button ) ;
2019-08-24 15:00:08 +02:00
return box ;
}
2020-05-22 17:02:24 +02:00
/// <summary>
/// Creates an array of groups with a fixed width that can be used to create a column structure
/// </summary>
/// <param name="parent">The element the groups should be added to, optional.</param>
/// <param name="totalSize">The total width of all of the groups combined</param>
/// <param name="amount">The amount of groups to split the total size into</param>
/// <param name="setHeightBasedOnChildren">Whether the groups should set their heights based on their children's heights</param>
/// <returns>An array of columns</returns>
2019-08-24 15:12:11 +02:00
public static Group [ ] MakeColumns ( Element parent , Vector2 totalSize , int amount , bool setHeightBasedOnChildren = true ) {
2019-08-24 14:34:08 +02:00
var cols = new Group [ amount ] ;
for ( var i = 0 ; i < amount ; i + + ) {
2019-09-11 15:03:10 +02:00
var anchor = i = = amount - 1 ? Anchor . AutoInlineIgnoreOverflow : Anchor . AutoInline ;
cols [ i ] = new Group ( anchor , new Vector2 ( totalSize . X / amount , totalSize . Y ) , setHeightBasedOnChildren ) ;
2019-08-24 15:12:11 +02:00
if ( parent ! = null )
parent . AddChild ( cols [ i ] ) ;
2019-08-24 14:34:08 +02:00
}
return cols ;
}
2020-05-22 17:02:24 +02:00
/// <summary>
/// Creates a <see cref="TextField"/> with a + and a - button next to it, to allow for easy number input.
/// </summary>
/// <param name="anchor">The text field's anchor</param>
/// <param name="size">The size of the text field</param>
/// <param name="defaultValue">The default content of the text field</param>
/// <param name="stepPerClick">The value that is added or removed to the text field's value when clicking the + or - buttons</param>
/// <param name="rule">The rule for text input. <see cref="TextField.OnlyNumbers"/> by default.</param>
/// <param name="onTextChange">A callback that is invoked when the text field's text changes</param>
/// <returns>A group that contains the number field</returns>
2019-08-24 12:40:20 +02:00
public static Group NumberField ( Anchor anchor , Vector2 size , int defaultValue = 0 , int stepPerClick = 1 , TextField . Rule rule = null , TextField . TextChanged onTextChange = null ) {
var group = new Group ( anchor , size , false ) ;
var field = new TextField ( Anchor . TopLeft , Vector2 . One , rule ? ? TextField . OnlyNumbers ) ;
field . OnTextChange = onTextChange ;
2019-09-05 12:51:40 +02:00
field . SetText ( defaultValue . ToString ( ) ) ;
2019-08-24 12:40:20 +02:00
group . AddChild ( field ) ;
group . OnAreaUpdated + = e = > field . Size = new Vector2 ( ( e . Area . Width - e . Area . Height / 2 ) / e . Scale , 1 ) ;
var upButton = new Button ( Anchor . TopRight , Vector2 . One , "+" ) {
2019-08-25 21:49:27 +02:00
OnPressed = element = > {
var text = field . Text . ToString ( ) ;
if ( int . TryParse ( text , out var val ) )
field . SetText ( val + stepPerClick ) ;
2019-08-24 12:40:20 +02:00
}
} ;
group . AddChild ( upButton ) ;
group . OnAreaUpdated + = e = > upButton . Size = new Vector2 ( e . Area . Height / 2 / e . Scale ) ;
var downButton = new Button ( Anchor . BottomRight , Vector2 . One , "-" ) {
2019-08-25 21:49:27 +02:00
OnPressed = element = > {
var text = field . Text . ToString ( ) ;
if ( int . TryParse ( text , out var val ) )
field . SetText ( val - stepPerClick ) ;
2019-08-24 12:40:20 +02:00
}
} ;
group . AddChild ( downButton ) ;
group . OnAreaUpdated + = e = > downButton . Size = new Vector2 ( e . Area . Height / 2 / e . Scale ) ;
return group ;
}
}
}