mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-12-25 01:39:23 +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;
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue