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:
parent
72efe55970
commit
adf0ce56cb
3 changed files with 84 additions and 42 deletions
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue