1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-11-26 06:28:35 +01:00

made ui scaling be based on the root element as well

This commit is contained in:
Ellpeck 2019-08-11 18:02:21 +02:00
parent 72efe55970
commit adf0ce56cb
3 changed files with 84 additions and 42 deletions

View file

@ -79,6 +79,14 @@ namespace MLEM.Ui.Elements {
} }
} }
protected InputHandler Input => this.System.InputHandler; protected InputHandler Input => this.System.InputHandler;
public RootElement Root { get; private set; }
public Rectangle ScaledViewport {
get {
var bounds = this.System.GraphicsDevice.Viewport;
return new Rectangle(bounds.X, bounds.Y, (bounds.Width / this.Root.ActualScale).Ceil(), (bounds.Height / this.Root.ActualScale).Ceil());
}
}
public Vector2 MousePos => this.Input.MousePosition.ToVector2() / this.Root.ActualScale;
public Element Parent { get; private set; } public Element Parent { get; private set; }
public bool IsMouseOver { get; private set; } public bool IsMouseOver { get; private set; }
public bool IsSelected { get; private set; } public bool IsSelected { get; private set; }
@ -119,8 +127,8 @@ namespace MLEM.Ui.Elements {
this.anchor = anchor; this.anchor = anchor;
this.size = size; this.size = size;
this.OnMouseEnter += (element, mousePos) => this.IsMouseOver = true; this.OnMouseEnter += element => this.IsMouseOver = true;
this.OnMouseExit += (element, mousePos) => this.IsMouseOver = false; this.OnMouseExit += element => this.IsMouseOver = false;
this.OnSelected += element => this.IsSelected = true; this.OnSelected += element => this.IsSelected = true;
this.OnDeselected += element => this.IsSelected = false; this.OnDeselected += element => this.IsSelected = false;
@ -132,6 +140,7 @@ namespace MLEM.Ui.Elements {
index = this.children.Count; index = this.children.Count;
this.children.Insert(index, element); this.children.Insert(index, element);
element.Parent = this; element.Parent = this;
element.PropagateRoot(this.Root);
element.PropagateUiSystem(this.System); element.PropagateUiSystem(this.System);
this.SetDirty(); this.SetDirty();
return element; return element;
@ -140,6 +149,7 @@ namespace MLEM.Ui.Elements {
public void RemoveChild(Element element) { public void RemoveChild(Element element) {
this.children.Remove(element); this.children.Remove(element);
element.Parent = null; element.Parent = null;
element.PropagateRoot(null);
element.PropagateUiSystem(null); element.PropagateUiSystem(null);
this.SetDirty(); this.SetDirty();
} }
@ -179,7 +189,7 @@ namespace MLEM.Ui.Elements {
parentArea.Width -= this.Parent.ChildPadding.X * 2; parentArea.Width -= this.Parent.ChildPadding.X * 2;
parentArea.Height -= this.Parent.ChildPadding.Y * 2; parentArea.Height -= this.Parent.ChildPadding.Y * 2;
} else { } else {
parentArea = this.System.ScaledViewport; parentArea = this.ScaledViewport;
} }
var parentCenterX = parentArea.X + parentArea.Width / 2; var parentCenterX = parentArea.X + parentArea.Width / 2;
var parentCenterY = parentArea.Y + parentArea.Height / 2; var parentCenterY = parentArea.Y + parentArea.Height / 2;
@ -297,20 +307,20 @@ namespace MLEM.Ui.Elements {
} }
} }
public virtual void DrawUnbound(GameTime time, SpriteBatch batch, float alpha, BlendState blendState = null, SamplerState samplerState = null) { public virtual void DrawUnbound(GameTime time, SpriteBatch batch, float alpha, float scale, BlendState blendState = null, SamplerState samplerState = null) {
foreach (var child in this.children) { foreach (var child in this.children) {
if (!child.IsHidden) if (!child.IsHidden)
child.DrawUnbound(time, batch, alpha * child.DrawAlpha, blendState, samplerState); child.DrawUnbound(time, batch, alpha * child.DrawAlpha, scale, blendState, samplerState);
} }
} }
public Element GetMousedElement(Vector2 mousePos) { public Element GetMousedElement() {
if (this.IsHidden || this.IgnoresMouse) if (this.IsHidden || this.IgnoresMouse)
return null; return null;
if (!this.Area.Contains(mousePos)) if (!this.Area.Contains(this.MousePos))
return null; return null;
for (var i = this.children.Count - 1; i >= 0; i--) { for (var i = this.children.Count - 1; i >= 0; i--) {
var element = this.children[i].GetMousedElement(mousePos); var element = this.children[i].GetMousedElement();
if (element != null) if (element != null)
return element; return element;
} }
@ -320,9 +330,9 @@ namespace MLEM.Ui.Elements {
protected virtual void InitStyle(UiStyle style) { protected virtual void InitStyle(UiStyle style) {
} }
public delegate void MouseClickCallback(Element element, Vector2 mousePos, MouseButton button); public delegate void MouseClickCallback(Element element, MouseButton button);
public delegate void MouseCallback(Element element, Vector2 mousePos); public delegate void MouseCallback(Element element);
public delegate void TextInputCallback(Element element, Keys key, char character); public delegate void TextInputCallback(Element element, Keys key, char character);
@ -334,6 +344,12 @@ namespace MLEM.Ui.Elements {
child.PropagateUiSystem(system); child.PropagateUiSystem(system);
} }
internal void PropagateRoot(RootElement root) {
this.Root = root;
foreach (var child in this.children)
child.PropagateRoot(root);
}
internal void PropagateInput(Keys key, char character) { internal void PropagateInput(Keys key, char character) {
this.OnTextInput?.Invoke(this, key, character); this.OnTextInput?.Invoke(this, key, character);
foreach (var child in this.children) foreach (var child in this.children)

View file

@ -16,7 +16,7 @@ namespace MLEM.Ui {
public readonly InputHandler InputHandler; public readonly InputHandler InputHandler;
private readonly bool isInputOurs; private readonly bool isInputOurs;
private float globalScale; private float globalScale = 1;
public float GlobalScale { public float GlobalScale {
get => this.globalScale; get => this.globalScale;
set { set {
@ -25,13 +25,6 @@ namespace MLEM.Ui {
root.Element.ForceUpdateArea(); root.Element.ForceUpdateArea();
} }
} }
public Rectangle ScaledViewport {
get {
var bounds = this.GraphicsDevice.Viewport.Bounds;
return new Rectangle(bounds.X, bounds.Y, (bounds.Width / this.globalScale).Floor(), (bounds.Height / this.globalScale).Floor());
}
}
public Vector2 MousePos => this.InputHandler.MousePosition.ToVector2() / this.globalScale;
public Element MousedElement { get; private set; } public Element MousedElement { get; private set; }
public Element SelectedElement { get; private set; } public Element SelectedElement { get; private set; }
private UiStyle style; private UiStyle style;
@ -72,9 +65,9 @@ namespace MLEM.Ui {
var mousedNow = this.GetMousedElement(); var mousedNow = this.GetMousedElement();
if (mousedNow != this.MousedElement) { if (mousedNow != this.MousedElement) {
if (this.MousedElement != null) if (this.MousedElement != null)
this.MousedElement.OnMouseExit?.Invoke(this.MousedElement, this.MousePos); this.MousedElement.OnMouseExit?.Invoke(this.MousedElement);
if (mousedNow != null) if (mousedNow != null)
mousedNow.OnMouseEnter?.Invoke(mousedNow, this.MousePos); mousedNow.OnMouseEnter?.Invoke(mousedNow);
this.MousedElement = mousedNow; this.MousedElement = mousedNow;
} }
@ -89,7 +82,7 @@ namespace MLEM.Ui {
if (mousedNow?.OnClicked != null) { if (mousedNow?.OnClicked != null) {
foreach (var button in InputHandler.MouseButtons) { foreach (var button in InputHandler.MouseButtons) {
if (this.InputHandler.IsMouseButtonPressed(button)) if (this.InputHandler.IsMouseButtonPressed(button))
mousedNow.OnClicked(mousedNow, this.MousePos, button); mousedNow.OnClicked(mousedNow, button);
} }
} }
@ -98,25 +91,29 @@ namespace MLEM.Ui {
} }
public void Draw(GameTime time, SpriteBatch batch) { public void Draw(GameTime time, SpriteBatch batch) {
batch.Begin(SpriteSortMode.Deferred, this.BlendState, this.SamplerState, transformMatrix: Matrix.CreateScale(this.globalScale));
foreach (var root in this.rootElements) { foreach (var root in this.rootElements) {
if (!root.Element.IsHidden) if (root.Element.IsHidden)
continue;
batch.Begin(SpriteSortMode.Deferred, this.BlendState, this.SamplerState, transformMatrix: Matrix.CreateScale(root.ActualScale));
root.Element.Draw(time, batch, this.DrawAlpha * root.Element.DrawAlpha); root.Element.Draw(time, batch, this.DrawAlpha * root.Element.DrawAlpha);
}
batch.End(); batch.End();
}
foreach (var root in this.rootElements) { foreach (var root in this.rootElements) {
if (!root.Element.IsHidden) if (!root.Element.IsHidden)
root.Element.DrawUnbound(time, batch, this.DrawAlpha * root.Element.DrawAlpha, this.BlendState, this.SamplerState); root.Element.DrawUnbound(time, batch, this.DrawAlpha * root.Element.DrawAlpha, root.ActualScale, this.BlendState, this.SamplerState);
} }
} }
public void Add(string name, Element root) { public RootElement Add(string name, Element root) {
if (this.IndexOf(name) >= 0) if (this.IndexOf(name) >= 0)
throw new ArgumentException($"There is already a root element with name {name}"); throw new ArgumentException($"There is already a root element with name {name}");
this.rootElements.Add(new RootElement(name, root)); var rootInst = new RootElement(name, root, this);
this.rootElements.Add(rootInst);
root.PropagateRoot(rootInst);
root.PropagateUiSystem(this); root.PropagateUiSystem(this);
return rootInst;
} }
public void Remove(string name) { public void Remove(string name) {
@ -126,9 +123,9 @@ namespace MLEM.Ui {
this.rootElements.RemoveAt(index); this.rootElements.RemoveAt(index);
} }
public Element Get(string name) { public RootElement Get(string name) {
var index = this.IndexOf(name); var index = this.IndexOf(name);
return index < 0 ? null : this.rootElements[index].Element; return index < 0 ? null : this.rootElements[index];
} }
private int IndexOf(string name) { private int IndexOf(string name) {
@ -137,7 +134,7 @@ namespace MLEM.Ui {
private Element GetMousedElement() { private Element GetMousedElement() {
foreach (var root in this.rootElements) { foreach (var root in this.rootElements) {
var moused = root.Element.GetMousedElement(this.MousePos); var moused = root.Element.GetMousedElement();
if (moused != null) if (moused != null)
return moused; return moused;
} }
@ -146,14 +143,27 @@ namespace MLEM.Ui {
} }
public struct RootElement { public class RootElement {
public readonly string Name; public readonly string Name;
public readonly Element Element; public readonly Element Element;
public readonly UiSystem System;
private float scale = 1;
public float Scale {
get => this.scale;
set {
if (this.scale == value)
return;
this.scale = value;
this.Element.ForceUpdateArea();
}
}
public float ActualScale => this.System.GlobalScale * this.Scale;
public RootElement(string name, Element element) { public RootElement(string name, Element element, UiSystem system) {
this.Name = name; this.Name = name;
this.Element = element; this.Element = element;
this.System = system;
} }
} }

View file

@ -1,4 +1,6 @@
using System; using System;
using System.Collections.Generic;
using Coroutine;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
@ -28,7 +30,7 @@ namespace Tests {
var style = new UiStyle { var style = new UiStyle {
Font = new GenericSpriteFont(LoadContent<SpriteFont>("Fonts/TestFont")), Font = new GenericSpriteFont(LoadContent<SpriteFont>("Fonts/TestFont")),
TextScale = 0.2F, TextScale = 0.8F,
PanelTexture = this.testPatch, PanelTexture = this.testPatch,
ButtonTexture = new NinePatch(new TextureRegion(this.testTexture, 24, 8, 16, 16), 4), ButtonTexture = new NinePatch(new TextureRegion(this.testTexture, 24, 8, 16, 16), 4),
TextFieldTexture = new NinePatch(new TextureRegion(this.testTexture, 24, 8, 16, 16), 4), TextFieldTexture = new NinePatch(new TextureRegion(this.testTexture, 24, 8, 16, 16), 4),
@ -37,21 +39,21 @@ namespace Tests {
}; };
var untexturedStyle = this.UiSystem.Style; var untexturedStyle = this.UiSystem.Style;
this.UiSystem.Style = style; this.UiSystem.Style = style;
this.UiSystem.GlobalScale = 5; this.UiSystem.GlobalScale = 1.25F;
var root = new Panel(Anchor.BottomLeft, new Vector2(100, 120), new Point(5, 5)); var root = new Panel(Anchor.Center, new Vector2(300, 450), Point.Zero);
this.UiSystem.Add("Test", root); this.UiSystem.Add("Test", root);
root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "This is a test text that is hopefully long enough to cover at least a few lines, otherwise it would be very sad.")); root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "This is a test text that is hopefully long enough to cover at least a few lines, otherwise it would be very sad."));
var image = root.AddChild(new Image(Anchor.AutoCenter, new Vector2(20, 20), new TextureRegion(this.testTexture, 0, 0, 8, 8)) {IsHidden = true}); var image = root.AddChild(new Image(Anchor.AutoCenter, new Vector2(50, 50), new TextureRegion(this.testTexture, 0, 0, 8, 8)) {IsHidden = true});
root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 15), "Test Button") { root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 40), "Test Button") {
OnClicked = (element, pos, button) => { OnClicked = (element, button) => {
if (button == MouseButton.Left) if (button == MouseButton.Left)
image.IsHidden = !image.IsHidden; image.IsHidden = !image.IsHidden;
} }
}); });
root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 15), "Change Style") { root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 40), "Change Style") {
OnClicked = (element, pos, button) => { OnClicked = (element, button) => {
if (button == MouseButton.Left) if (button == MouseButton.Left)
this.UiSystem.Style = this.UiSystem.Style is UntexturedStyle ? style : untexturedStyle; this.UiSystem.Style = this.UiSystem.Style is UntexturedStyle ? style : untexturedStyle;
}, },
@ -59,7 +61,21 @@ namespace Tests {
Texture = this.testPatch, Texture = this.testPatch,
HoveredColor = Color.LightGray HoveredColor = Color.LightGray
}); });
root.AddChild(new TextField(Anchor.AutoLeft, new Vector2(1, 15))); root.AddChild(new TextField(Anchor.AutoLeft, new Vector2(1, 40)));
root.AddChild(new VerticalSpace(3));
root.AddChild(new Button(Anchor.AutoLeft, new Vector2(40), "+") {
OnClicked = (element, button) => {
if (element.Root.Scale < 2)
element.Root.Scale += 0.1F;
}
});
root.AddChild(new Button(Anchor.AutoInline, new Vector2(40), "-") {
OnClicked = (element, button) => {
if (element.Root.Scale > 0.5F)
element.Root.Scale -= 0.1F;
}
});
} }
protected override void Draw(GameTime gameTime) { protected override void Draw(GameTime gameTime) {