06 GUI: refactor button code and add basic scenes

This commit is contained in:
0xdeadbeer 2023-12-06 22:15:20 +01:00
parent 8a99476507
commit cad444e05d
7 changed files with 296 additions and 89 deletions

View File

@ -13,3 +13,15 @@
#---------------------------------- Content ---------------------------------# #---------------------------------- Content ---------------------------------#
#begin button-default-texture.png
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:button-default-texture.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 B

View File

@ -1,4 +1,6 @@
using Microsoft.Xna.Framework; using System;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
using GUI.UIElements; using GUI.UIElements;
@ -9,7 +11,7 @@ public class Game1 : Game
{ {
private GraphicsDeviceManager _graphics; private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch; private SpriteBatch _spriteBatch;
private Button mainButton; private Scene mainScene;
public Game1() public Game1()
{ {
@ -20,14 +22,34 @@ public class Game1 : Game
protected override void Initialize() protected override void Initialize()
{ {
mainButton = new Button(new Vector2(10.0f, 10.0f), new Vector2(80.0f, 40.0f), null, _graphics); _spriteBatch = new SpriteBatch(GraphicsDevice);
Scene.graphics = _graphics;
Scene.spriteBatch = _spriteBatch;
Scene.content = Content;
mainScene = new Scene();
DrawableData drawableData = new DrawableData(null);
drawableData.scale = new Vector2(80.0f, 40.0f);
void buttonOnClick(Button obj)
{
Console.WriteLine("ACTION CALLED SUCCESSFULLY!");
}
ButtonData buttonData = new ButtonData(buttonOnClick);
buttonData.bgColor = Color.Red;
buttonData.fgColor = Color.White;
Button mainButton = new Button(drawableData, buttonData);
mainScene.drawables.Add(mainButton);
base.Initialize(); base.Initialize();
} }
protected override void LoadContent() protected override void LoadContent()
{ {
_spriteBatch = new SpriteBatch(GraphicsDevice);
} }
protected override void Update(GameTime gameTime) protected override void Update(GameTime gameTime)
@ -35,7 +57,7 @@ public class Game1 : Game
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit(); Exit();
mainButton.Update(gameTime); mainScene.Update(gameTime);
base.Update(gameTime); base.Update(gameTime);
} }
@ -44,9 +66,7 @@ public class Game1 : Game
{ {
GraphicsDevice.Clear(Color.Black); GraphicsDevice.Clear(Color.Black);
_spriteBatch.Begin(); mainScene.Draw(gameTime);
mainButton.Draw(_spriteBatch, gameTime);
_spriteBatch.End();
base.Draw(gameTime); base.Draw(gameTime);
} }

View File

@ -0,0 +1,136 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Vector2 = Microsoft.Xna.Framework.Vector2;
namespace GUI.UIElements;
public class ButtonData
{
public Color bgColor;
public Color fgColor;
public Color hoverBgColor;
public Color hoverFgColor;
public Color pressedBgColor;
public Color pressedFgColor;
public bool isPressed = false;
public bool isReleased = false;
public bool isHovered = false;
public bool isNone = false;
public Action<Button>? onClick;
public ButtonData(Action<Button>? onClick)
{
this.onClick = onClick;
}
}
public class Button : Drawable
{
private DrawableData _drawableData;
public ButtonData _buttonData;
public Button(DrawableData data, ButtonData buttonData)
{
_drawableData = data;
_buttonData = buttonData;
}
public override void Initialize(GameTime gameTime)
{
}
void onPressed()
{
if (_buttonData.isPressed)
return;
Console.WriteLine("I'm being pressed!");
_buttonData.bgColor = Color.Red;
_buttonData.onClick(this);
_buttonData.isReleased = false;
_buttonData.isPressed = true;
}
void onReleased()
{
if (!_buttonData.isPressed)
return;
_buttonData.bgColor = Color.Yellow;
_buttonData.isPressed = false;
_buttonData.isReleased = true;
}
void onHovered()
{
if (_buttonData.isHovered)
return;
Console.WriteLine("I'm being hovered!");
_buttonData.bgColor = Color.Yellow;
_buttonData.isHovered = true;
}
void onNone()
{
_buttonData.bgColor = Color.Red;
_buttonData.isPressed = false;
_buttonData.isReleased = false;
_buttonData.isHovered = false;
}
public override void Update(GameTime gameTime)
{
var mstate = Mouse.GetState();
Vector2 mousePosition = mstate.Position.ToVector2();
bool outsideHorizontalBoundary = (mousePosition.X < _drawableData.position.X) || (mousePosition.X > (_drawableData.position.X + _drawableData.scale.X));
bool outsideVerticalBoundary = (mousePosition.Y < _drawableData.position.Y) || (mousePosition.Y > (_drawableData.position.Y + _drawableData.scale.Y));
if (outsideHorizontalBoundary || outsideVerticalBoundary)
{
onNone();
return;
}
if (mstate.LeftButton == ButtonState.Pressed)
{
onPressed();
return;
}
if (mstate.LeftButton == ButtonState.Released)
{
onReleased();
}
onHovered();
}
public override void Draw(GameTime gameTime)
{
Scene.spriteBatch.Draw(
_drawableData.texture,
_drawableData.position,
null,
_buttonData.bgColor,
0.0f,
Vector2.Zero,
_drawableData.scale,
SpriteEffects.None,
0f
);
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Data;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace GUI.UIElements;
public class DrawableData
{
public Texture2D texture;
public Vector2 position = Vector2.Zero;
public Vector2 scale = Vector2.One;
public float rotation = 0.0f;
public DrawableData(Texture2D? texture)
{
if (texture is not null)
{
this.texture = texture;
return;
}
this.texture = Scene.content.Load<Texture2D>("button-default-texture");
}
}
public enum DrawableType
{
Container,
Text,
Button,
}
public abstract class Drawable
{
public DrawableType drawableType;
public abstract void Initialize(GameTime gameTime);
public abstract void Update(GameTime gameTime);
public abstract void Draw(GameTime gameTime);
}

View File

@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace GUI.UIElements;
public class Scene
{
private static ContentManager? _content;
public static ContentManager content
{
get { return _content; }
set
{
if (_content is not null)
return;
_content = value;
}
}
private static GraphicsDeviceManager? _graphics;
public static GraphicsDeviceManager graphics
{
get { return _graphics; }
set
{
if (_graphics is not null)
return;
_graphics = value;
}
}
private static SpriteBatch? _spriteBatch;
public static SpriteBatch spriteBatch
{
get { return _spriteBatch; }
set
{
if (_spriteBatch is not null)
return;
_spriteBatch = value;
}
}
public List<Drawable> drawables;
public Scene()
{
drawables = new List<Drawable>();
}
public void Initialize(GameTime gameTime)
{
}
public void Update(GameTime gameTime)
{
foreach (Drawable drawable in drawables)
{
drawable.Update(gameTime);
}
}
public void Draw(GameTime gameTime)
{
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
foreach (Drawable drawable in drawables)
{
drawable.Draw(gameTime);
}
spriteBatch.End();
}
}

View File

@ -1,81 +0,0 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Vector2 = Microsoft.Xna.Framework.Vector2;
namespace GUI.UIElements;
public class Button
{
private Texture2D texture;
private Vector2 pos;
private Vector2 size;
private float rot;
private Color _bgColor;
public Color bgColor
{
get { return _bgColor; }
set
{
_bgColor = value;
texture.SetData(new Color[] { _bgColor });
}
}
public Button(Vector2? pos, Vector2? size, float? rot, GraphicsDeviceManager graphics)
{
this.pos = pos ?? Vector2.Zero;
this.size = size ?? Vector2.One;
this.rot = rot ?? 0.0f;
texture = new Texture2D(graphics.GraphicsDevice, 1, 1);
bgColor = Color.Green;
}
public void OnClick(GameTime gameTime)
{
Console.WriteLine("You pressed a button!");
this.bgColor = Color.Yellow;
}
public void OnHover(GameTime gameTime)
{
Console.WriteLine("You're hovering over the button!");
this.bgColor = Color.Red;
}
public void NoEvent(GameTime gameTime)
{
this.bgColor = Color.Green;
}
public void Update(GameTime gameTime)
{
var mstate = Mouse.GetState();
Vector2 mousePosition = mstate.Position.ToVector2();
bool insideHorizontalBoundary = (mousePosition.X > pos.X) && (mousePosition.X < (pos.X + size.X));
bool insideVerticalBoundary = (mousePosition.Y > pos.Y) && (mousePosition.Y < (pos.Y + size.Y));
if (!insideHorizontalBoundary || !insideVerticalBoundary)
{
this.NoEvent(gameTime);
return;
}
if (Mouse.GetState().LeftButton == ButtonState.Pressed)
{
this.OnClick(gameTime);
return;
}
this.OnHover(gameTime);
}
public void Draw(SpriteBatch spriteBatch, GameTime gameTime)
{
spriteBatch.Draw(texture, new Rectangle((int) pos.X, (int) pos.Y, (int) size.X, (int) size.Y), Color.White);
}
}