1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-06-07 07:13:38 +02: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;
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 bool IsMouseOver { get; private set; }
public bool IsSelected { get; private set; }
@ -119,8 +127,8 @@ namespace MLEM.Ui.Elements {
this.anchor = anchor;
this.size = size;
this.OnMouseEnter += (element, mousePos) => this.IsMouseOver = true;
this.OnMouseExit += (element, mousePos) => this.IsMouseOver = false;
this.OnMouseEnter += element => this.IsMouseOver = true;
this.OnMouseExit += element => this.IsMouseOver = false;
this.OnSelected += element => this.IsSelected = true;
this.OnDeselected += element => this.IsSelected = false;
@ -132,6 +140,7 @@ namespace MLEM.Ui.Elements {
index = this.children.Count;
this.children.Insert(index, element);
element.Parent = this;
element.PropagateRoot(this.Root);
element.PropagateUiSystem(this.System);
this.SetDirty();
return element;
@ -140,6 +149,7 @@ namespace MLEM.Ui.Elements {
public void RemoveChild(Element element) {
this.children.Remove(element);
element.Parent = null;
element.PropagateRoot(null);
element.PropagateUiSystem(null);
this.SetDirty();
}
@ -179,7 +189,7 @@ namespace MLEM.Ui.Elements {
parentArea.Width -= this.Parent.ChildPadding.X * 2;
parentArea.Height -= this.Parent.ChildPadding.Y * 2;
} else {
parentArea = this.System.ScaledViewport;
parentArea = this.ScaledViewport;
}
var parentCenterX = parentArea.X + parentArea.Width / 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) {
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)
return null;
if (!this.Area.Contains(mousePos))
if (!this.Area.Contains(this.MousePos))
return null;
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)
return element;
}
@ -320,9 +330,9 @@ namespace MLEM.Ui.Elements {
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);
@ -334,6 +344,12 @@ namespace MLEM.Ui.Elements {
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) {
this.OnTextInput?.Invoke(this, key, character);
foreach (var child in this.children)

View file

@ -16,7 +16,7 @@ namespace MLEM.Ui {
public readonly InputHandler InputHandler;
private readonly bool isInputOurs;
private float globalScale;
private float globalScale = 1;
public float GlobalScale {
get => this.globalScale;
set {
@ -25,13 +25,6 @@ namespace MLEM.Ui {
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 SelectedElement { get; private set; }
private UiStyle style;
@ -72,9 +65,9 @@ namespace MLEM.Ui {
var mousedNow = this.GetMousedElement();
if (mousedNow != this.MousedElement) {
if (this.MousedElement != null)
this.MousedElement.OnMouseExit?.Invoke(this.MousedElement, this.MousePos);
this.MousedElement.OnMouseExit?.Invoke(this.MousedElement);
if (mousedNow != null)
mousedNow.OnMouseEnter?.Invoke(mousedNow, this.MousePos);
mousedNow.OnMouseEnter?.Invoke(mousedNow);
this.MousedElement = mousedNow;
}
@ -89,7 +82,7 @@ namespace MLEM.Ui {
if (mousedNow?.OnClicked != null) {
foreach (var button in InputHandler.MouseButtons) {
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) {
batch.Begin(SpriteSortMode.Deferred, this.BlendState, this.SamplerState, transformMatrix: Matrix.CreateScale(this.globalScale));
foreach (var root in this.rootElements) {
if (!root.Element.IsHidden)
root.Element.Draw(time, batch, this.DrawAlpha * root.Element.DrawAlpha);
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);
batch.End();
}
batch.End();
foreach (var root in this.rootElements) {
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)
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);
return rootInst;
}
public void Remove(string name) {
@ -126,9 +123,9 @@ namespace MLEM.Ui {
this.rootElements.RemoveAt(index);
}
public Element Get(string name) {
public RootElement Get(string 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) {
@ -137,7 +134,7 @@ namespace MLEM.Ui {
private Element GetMousedElement() {
foreach (var root in this.rootElements) {
var moused = root.Element.GetMousedElement(this.MousePos);
var moused = root.Element.GetMousedElement();
if (moused != null)
return moused;
}
@ -146,14 +143,27 @@ namespace MLEM.Ui {
}
public struct RootElement {
public class RootElement {
public readonly string Name;
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.Element = element;
this.System = system;
}
}

View file

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using Coroutine;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
@ -28,7 +30,7 @@ namespace Tests {
var style = new UiStyle {
Font = new GenericSpriteFont(LoadContent<SpriteFont>("Fonts/TestFont")),
TextScale = 0.2F,
TextScale = 0.8F,
PanelTexture = this.testPatch,
ButtonTexture = 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;
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);
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});
root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 15), "Test Button") {
OnClicked = (element, pos, button) => {
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, 40), "Test Button") {
OnClicked = (element, button) => {
if (button == MouseButton.Left)
image.IsHidden = !image.IsHidden;
}
});
root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 15), "Change Style") {
OnClicked = (element, pos, button) => {
root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 40), "Change Style") {
OnClicked = (element, button) => {
if (button == MouseButton.Left)
this.UiSystem.Style = this.UiSystem.Style is UntexturedStyle ? style : untexturedStyle;
},
@ -59,7 +61,21 @@ namespace Tests {
Texture = this.testPatch,
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) {