mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-12-25 01:39:23 +01:00
added scroll bar and overflow handling panel
This commit is contained in:
parent
09fbdfd54e
commit
4624219b4e
13 changed files with 245 additions and 60 deletions
|
@ -26,7 +26,7 @@ namespace Examples {
|
|||
this.testPatch = new NinePatch(new TextureRegion(this.testTexture, 0, 8, 24, 24), 8);
|
||||
base.LoadContent();
|
||||
|
||||
var style = new UiStyle {
|
||||
var style = new UntexturedStyle(this.SpriteBatch) {
|
||||
Font = new GenericSpriteFont(LoadContent<SpriteFont>("Fonts/TestFont")),
|
||||
TextScale = 0.2F,
|
||||
PanelTexture = this.testPatch,
|
||||
|
@ -39,7 +39,7 @@ namespace Examples {
|
|||
this.UiSystem.Style = style;
|
||||
this.UiSystem.GlobalScale = 5;
|
||||
|
||||
var root = new Panel(Anchor.Center, new Vector2(100, 120), Point.Zero, true);
|
||||
var root = new Panel(Anchor.Center, new Vector2(100, 80), Point.Zero, false, true, new Point(5, 10));
|
||||
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."));
|
||||
|
@ -53,7 +53,7 @@ namespace Examples {
|
|||
root.AddChild(new Button(Anchor.AutoCenter, new Vector2(1, 15), "Change Style") {
|
||||
OnClicked = (element, button) => {
|
||||
if (button == MouseButton.Left)
|
||||
this.UiSystem.Style = this.UiSystem.Style is UntexturedStyle ? style : untexturedStyle;
|
||||
this.UiSystem.Style = this.UiSystem.Style == untexturedStyle ? style : untexturedStyle;
|
||||
},
|
||||
HasCustomStyle = true,
|
||||
Texture = this.testPatch,
|
||||
|
@ -75,6 +75,7 @@ namespace Examples {
|
|||
}
|
||||
});
|
||||
root.AddChild(new Button(Anchor.AutoInline, new Vector2(30, 15), "Woop") {
|
||||
PositionOffset = new Point(2, 0),
|
||||
OnClicked = (element, button) => CoroutineHandler.Start(Woop(element))
|
||||
});
|
||||
}
|
||||
|
|
|
@ -38,10 +38,10 @@ namespace MLEM.Ui.Elements {
|
|||
} while (measure.X <= this.DisplayArea.Size.X / this.Scale && measure.Y <= this.DisplayArea.Size.Y / this.Scale);
|
||||
}
|
||||
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha) {
|
||||
var pos = this.DisplayArea.Location.ToVector2() + this.DisplayArea.Size.ToVector2() / 2;
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, Point offset) {
|
||||
var pos = this.DisplayArea.Location.ToVector2() + this.DisplayArea.Size.ToVector2() / 2 + offset.ToVector2();
|
||||
this.font.DrawCenteredString(batch, this.Text, pos, this.textScale * this.Scale, this.Color * alpha, true, true);
|
||||
base.Draw(time, batch, alpha);
|
||||
base.Draw(time, batch, alpha, offset);
|
||||
}
|
||||
|
||||
protected override void InitStyle(UiStyle style) {
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
}
|
||||
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha) {
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, Point offset) {
|
||||
var tex = this.Texture;
|
||||
var color = Color.White * alpha;
|
||||
if (this.IsMouseOver) {
|
||||
|
@ -29,8 +29,8 @@ namespace MLEM.Ui.Elements {
|
|||
tex = this.HoveredTexture;
|
||||
color = this.HoveredColor * alpha;
|
||||
}
|
||||
batch.Draw(tex, this.DisplayArea, color, this.Scale);
|
||||
base.Draw(time, batch, alpha);
|
||||
batch.Draw(tex, this.DisplayArea.OffsetCopy(offset), color, this.Scale);
|
||||
base.Draw(time, batch, alpha, offset);
|
||||
}
|
||||
|
||||
protected override void InitStyle(UiStyle style) {
|
||||
|
|
|
@ -63,6 +63,15 @@ namespace MLEM.Ui.Elements {
|
|||
this.SetAreaDirty();
|
||||
}
|
||||
}
|
||||
public Rectangle ChildPaddedArea {
|
||||
get {
|
||||
var padded = this.Area;
|
||||
padded.Location += this.ScaledChildPadding;
|
||||
padded.Width -= this.ScaledChildPadding.X * 2;
|
||||
padded.Height -= this.ScaledChildPadding.Y * 2;
|
||||
return padded;
|
||||
}
|
||||
}
|
||||
public Point ScaledChildPadding => this.childPadding.Multiply(this.Scale);
|
||||
|
||||
public MouseClickCallback OnClicked;
|
||||
|
@ -143,38 +152,42 @@ namespace MLEM.Ui.Elements {
|
|||
this.SetAreaDirty();
|
||||
}
|
||||
|
||||
public T AddChild<T>(T element, int index = -1) where T : Element {
|
||||
public T AddChild<T>(T element, int index = -1, bool propagateInfo = true) where T : Element {
|
||||
if (index < 0 || index > this.Children.Count)
|
||||
index = this.Children.Count;
|
||||
this.Children.Insert(index, element);
|
||||
element.Parent = this;
|
||||
element.PropagateRoot(this.Root);
|
||||
element.PropagateUiSystem(this.System);
|
||||
if (propagateInfo) {
|
||||
element.Parent = this;
|
||||
element.PropagateRoot(this.Root);
|
||||
element.PropagateUiSystem(this.System);
|
||||
}
|
||||
this.SetSortedChildrenDirty();
|
||||
this.SetAreaDirty();
|
||||
return element;
|
||||
}
|
||||
|
||||
public void RemoveChild(Element element) {
|
||||
public void RemoveChild(Element element, bool propagateInfo = true) {
|
||||
this.Children.Remove(element);
|
||||
element.Parent = null;
|
||||
element.PropagateRoot(null);
|
||||
element.PropagateUiSystem(null);
|
||||
if (propagateInfo) {
|
||||
element.Parent = null;
|
||||
element.PropagateRoot(null);
|
||||
element.PropagateUiSystem(null);
|
||||
}
|
||||
this.SetSortedChildrenDirty();
|
||||
this.SetAreaDirty();
|
||||
}
|
||||
|
||||
public void MoveToFront() {
|
||||
if (this.Parent != null) {
|
||||
this.Parent.RemoveChild(this);
|
||||
this.Parent.AddChild(this);
|
||||
this.Parent.RemoveChild(this, false);
|
||||
this.Parent.AddChild(this, -1, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveToBack() {
|
||||
if (this.Parent != null) {
|
||||
this.Parent.RemoveChild(this);
|
||||
this.Parent.AddChild(this, 0);
|
||||
this.Parent.RemoveChild(this, false);
|
||||
this.Parent.AddChild(this, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,15 +219,7 @@ namespace MLEM.Ui.Elements {
|
|||
public virtual void ForceUpdateArea() {
|
||||
this.areaDirty = false;
|
||||
|
||||
Rectangle parentArea;
|
||||
if (this.Parent != null) {
|
||||
parentArea = this.Parent.area;
|
||||
parentArea.Location += this.Parent.ScaledChildPadding;
|
||||
parentArea.Width -= this.Parent.ScaledChildPadding.X * 2;
|
||||
parentArea.Height -= this.Parent.ScaledChildPadding.Y * 2;
|
||||
} else {
|
||||
parentArea = this.system.GraphicsDevice.Viewport.Bounds;
|
||||
}
|
||||
var parentArea = this.Parent != null ? this.Parent.ChildPaddedArea : this.system.Viewport;
|
||||
var parentCenterX = parentArea.X + parentArea.Width / 2;
|
||||
var parentCenterY = parentArea.Y + parentArea.Height / 2;
|
||||
|
||||
|
@ -338,17 +343,17 @@ namespace MLEM.Ui.Elements {
|
|||
child.Update(time);
|
||||
}
|
||||
|
||||
public virtual void Draw(GameTime time, SpriteBatch batch, float alpha) {
|
||||
public virtual void Draw(GameTime time, SpriteBatch batch, float alpha, Point offset) {
|
||||
foreach (var child in this.SortedChildren) {
|
||||
if (!child.IsHidden)
|
||||
child.Draw(time, batch, alpha * child.DrawAlpha);
|
||||
child.Draw(time, batch, alpha * child.DrawAlpha, offset);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void DrawUnbound(GameTime time, SpriteBatch batch, float alpha, float scale, BlendState blendState = null, SamplerState samplerState = null) {
|
||||
public virtual void DrawUnbound(GameTime time, SpriteBatch batch, float alpha, BlendState blendState = null, SamplerState samplerState = null) {
|
||||
foreach (var child in this.SortedChildren) {
|
||||
if (!child.IsHidden)
|
||||
child.DrawUnbound(time, batch, alpha * child.DrawAlpha, scale, blendState, samplerState);
|
||||
child.DrawUnbound(time, batch, alpha * child.DrawAlpha, blendState, samplerState);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@ namespace MLEM.Ui.Elements {
|
|||
return this.scaleToImage ? this.texture.Size : base.CalcActualSize(parentArea);
|
||||
}
|
||||
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha) {
|
||||
batch.Draw(this.texture, this.DisplayArea, this.Color * alpha);
|
||||
base.Draw(time, batch, alpha);
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, Point offset) {
|
||||
batch.Draw(this.texture, this.DisplayArea.OffsetCopy(offset), this.Color * alpha);
|
||||
base.Draw(time, batch, alpha, offset);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using MLEM.Extensions;
|
||||
using MLEM.Textures;
|
||||
using MLEM.Ui.Style;
|
||||
|
||||
|
@ -7,17 +10,107 @@ namespace MLEM.Ui.Elements {
|
|||
public class Panel : Element {
|
||||
|
||||
public NinePatch Texture;
|
||||
public readonly ScrollBar ScrollBar;
|
||||
private readonly bool scrollOverflow;
|
||||
private RenderTarget2D renderTarget;
|
||||
|
||||
public Panel(Anchor anchor, Vector2 size, Point positionOffset, bool setHeightBasedOnChildren = false, NinePatch texture = null) : base(anchor, size) {
|
||||
this.Texture = texture;
|
||||
public Panel(Anchor anchor, Vector2 size, Point positionOffset, bool setHeightBasedOnChildren = false, bool scrollOverflow = false, Point? scrollerSize = null) : base(anchor, size) {
|
||||
this.PositionOffset = positionOffset;
|
||||
this.SetHeightBasedOnChildren = setHeightBasedOnChildren;
|
||||
this.scrollOverflow = scrollOverflow;
|
||||
this.ChildPadding = new Point(5);
|
||||
|
||||
if (scrollOverflow) {
|
||||
var scrollSize = scrollerSize ?? Point.Zero;
|
||||
this.ScrollBar = new ScrollBar(Anchor.TopRight, new Vector2(scrollSize.X, 1), scrollSize.Y, 0) {
|
||||
StepPerScroll = 10,
|
||||
OnValueChanged = (element, value) => {
|
||||
var firstChild = this.Children[0];
|
||||
// if the first child is the scrollbar, there are no other children
|
||||
if (firstChild == element)
|
||||
return;
|
||||
// as all children have to be auto-aligned, moving the first one up will move all others
|
||||
firstChild.PositionOffset = new Point(firstChild.PositionOffset.X, -value.Ceil());
|
||||
this.ForceUpdateArea();
|
||||
}
|
||||
};
|
||||
this.AddChild(this.ScrollBar);
|
||||
|
||||
// modify the padding so that the scroll bar isn't over top of something else
|
||||
this.ScrollBar.PositionOffset -= new Point(scrollSize.X + 1, 0);
|
||||
this.ChildPadding += new Point(scrollSize.X, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha) {
|
||||
batch.Draw(this.Texture, this.DisplayArea, Color.White * alpha, this.Scale);
|
||||
base.Draw(time, batch, alpha);
|
||||
public override void ForceUpdateArea() {
|
||||
if (this.scrollOverflow) {
|
||||
// sanity check
|
||||
if (this.SetHeightBasedOnChildren)
|
||||
throw new NotSupportedException("A panel can't both set height based on children and scroll overflow");
|
||||
foreach (var child in this.Children) {
|
||||
if (child != this.ScrollBar && child.Anchor < Anchor.AutoLeft)
|
||||
throw new NotSupportedException($"A panel that handles overflow can't contain non-automatic anchors ({child})");
|
||||
if (child is Panel panel && panel.scrollOverflow)
|
||||
throw new NotSupportedException($"A panel that scrolls overflow cannot contain another panel that scrolls overflow ({child})");
|
||||
}
|
||||
|
||||
// move the scrollbar to the front so it isn't used for auto-aligning
|
||||
this.ScrollBar.MoveToFront();
|
||||
}
|
||||
|
||||
base.ForceUpdateArea();
|
||||
|
||||
if (this.scrollOverflow) {
|
||||
var firstChild = this.Children[0];
|
||||
// if the first child is the scrollbar, then we know there's no other children
|
||||
if (firstChild == this.ScrollBar)
|
||||
return;
|
||||
var lastChild = this.Children[this.Children.Count - 2];
|
||||
// the max value of the scrollbar is the amount of non-scaled pixels taken up by overflowing components
|
||||
var childrenHeight = lastChild.Area.Bottom - firstChild.Area.Top;
|
||||
this.ScrollBar.MaxValue = (childrenHeight - this.Area.Height) / this.Scale + this.ChildPadding.Y * 2;
|
||||
|
||||
// update the render target
|
||||
var targetArea = this.GetRenderTargetArea();
|
||||
if (this.renderTarget == null || targetArea.Width != this.renderTarget.Width || targetArea.Height != this.renderTarget.Height) {
|
||||
if (this.renderTarget != null)
|
||||
this.renderTarget.Dispose();
|
||||
this.renderTarget = new RenderTarget2D(this.System.GraphicsDevice, targetArea.Width, targetArea.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, Point offset) {
|
||||
batch.Draw(this.Texture, this.DisplayArea.OffsetCopy(offset), Color.White * alpha, this.Scale);
|
||||
// if we handle overflow, draw using the render target in DrawUnbound
|
||||
if (!this.scrollOverflow) {
|
||||
base.Draw(time, batch, alpha, offset);
|
||||
} else {
|
||||
// draw the actual render target (don't apply the alpha here because it's already drawn onto with alpha)
|
||||
batch.Draw(this.renderTarget, this.GetRenderTargetArea().OffsetCopy(offset), Color.White);
|
||||
}
|
||||
}
|
||||
|
||||
public override void DrawUnbound(GameTime time, SpriteBatch batch, float alpha, BlendState blendState = null, SamplerState samplerState = null) {
|
||||
if (this.scrollOverflow) {
|
||||
// draw children onto the render target
|
||||
batch.GraphicsDevice.SetRenderTarget(this.renderTarget);
|
||||
batch.GraphicsDevice.Clear(Color.Transparent);
|
||||
batch.Begin(SpriteSortMode.Deferred, blendState, samplerState);
|
||||
// offset children by the render target's location
|
||||
var area = this.GetRenderTargetArea();
|
||||
base.Draw(time, batch, alpha, new Point(-area.X, -area.Y));
|
||||
batch.End();
|
||||
batch.GraphicsDevice.SetRenderTarget(null);
|
||||
}
|
||||
base.DrawUnbound(time, batch, alpha, blendState, samplerState);
|
||||
}
|
||||
|
||||
private Rectangle GetRenderTargetArea() {
|
||||
var area = this.ChildPaddedArea;
|
||||
area.X = this.DisplayArea.X;
|
||||
area.Width = this.DisplayArea.Width;
|
||||
return area;
|
||||
}
|
||||
|
||||
protected override void InitStyle(UiStyle style) {
|
||||
|
|
|
@ -46,19 +46,18 @@ namespace MLEM.Ui.Elements {
|
|||
return new Point(size.X, height.Ceil());
|
||||
}
|
||||
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha) {
|
||||
base.Draw(time, batch, alpha);
|
||||
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, Point offset) {
|
||||
var pos = this.DisplayArea.Location.ToVector2();
|
||||
var offset = new Vector2();
|
||||
var off = offset.ToVector2();
|
||||
foreach (var line in this.splitText) {
|
||||
if (this.centerText) {
|
||||
this.font.DrawCenteredString(batch, line, pos + offset + new Vector2(this.DisplayArea.Width / 2, 0), this.TextScale * this.Scale, Color.White * alpha);
|
||||
this.font.DrawCenteredString(batch, line, pos + off + new Vector2(this.DisplayArea.Width / 2, 0), this.TextScale * this.Scale, Color.White * alpha);
|
||||
} else {
|
||||
this.font.DrawString(batch, line, pos + offset, Color.White * alpha, 0, Vector2.Zero, this.TextScale * this.Scale, SpriteEffects.None, 0);
|
||||
this.font.DrawString(batch, line, pos + off, Color.White * alpha, 0, Vector2.Zero, this.TextScale * this.Scale, SpriteEffects.None, 0);
|
||||
}
|
||||
offset.Y += this.lineHeight + 1;
|
||||
off.Y += this.lineHeight + 1;
|
||||
}
|
||||
base.Draw(time, batch, alpha, offset);
|
||||
}
|
||||
|
||||
protected override void InitStyle(UiStyle style) {
|
||||
|
|
71
MLEM.Ui/Elements/ScrollBar.cs
Normal file
71
MLEM.Ui/Elements/ScrollBar.cs
Normal file
|
@ -0,0 +1,71 @@
|
|||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using MLEM.Extensions;
|
||||
using MLEM.Textures;
|
||||
using MLEM.Ui.Style;
|
||||
|
||||
namespace MLEM.Ui.Elements {
|
||||
public class ScrollBar : Element {
|
||||
|
||||
public NinePatch Background;
|
||||
public NinePatch ScrollerTexture;
|
||||
public Color HoveredColor;
|
||||
public Point ScrollerOffset;
|
||||
public Point ScrollerSize;
|
||||
private float maxValue;
|
||||
public float MaxValue {
|
||||
get => this.maxValue;
|
||||
set {
|
||||
this.maxValue = Math.Max(0, value);
|
||||
// force current value to be clamped
|
||||
this.CurrentValue = this.currValue;
|
||||
}
|
||||
}
|
||||
private float currValue;
|
||||
public float CurrentValue {
|
||||
get => this.currValue;
|
||||
set {
|
||||
var val = MathHelper.Clamp(value, 0, this.maxValue);
|
||||
if (this.currValue != val) {
|
||||
this.currValue = val;
|
||||
this.OnValueChanged?.Invoke(this, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
public float StepPerScroll = 1;
|
||||
public ValueChanged OnValueChanged;
|
||||
|
||||
public ScrollBar(Anchor anchor, Vector2 size, int scrollerHeight, float maxValue) : base(anchor, size) {
|
||||
this.maxValue = maxValue;
|
||||
this.ScrollerSize = new Point(size.X.Floor(), scrollerHeight);
|
||||
}
|
||||
|
||||
public override void Update(GameTime time) {
|
||||
base.Update(time);
|
||||
var scroll = this.Input.LastScrollWheel - this.Input.ScrollWheel;
|
||||
if (scroll != 0)
|
||||
this.CurrentValue += this.StepPerScroll * Math.Sign(scroll);
|
||||
}
|
||||
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, Point offset) {
|
||||
batch.Draw(this.Background, this.DisplayArea.OffsetCopy(offset), Color.White * alpha, this.Scale);
|
||||
|
||||
var scrollerPos = new Point(this.DisplayArea.X + offset.X + this.ScrollerOffset.X, this.DisplayArea.Y + offset.Y + this.ScrollerOffset.Y);
|
||||
var scrollerYOffset = (this.currValue / this.maxValue * (this.DisplayArea.Height - this.ScrollerSize.Y * this.Scale)).Floor();
|
||||
var scrollerRect = new Rectangle(scrollerPos + new Point(0, scrollerYOffset), this.ScrollerSize.Multiply(this.Scale));
|
||||
batch.Draw(this.ScrollerTexture, scrollerRect, Color.White * alpha, this.Scale);
|
||||
base.Draw(time, batch, alpha, offset);
|
||||
}
|
||||
|
||||
protected override void InitStyle(UiStyle style) {
|
||||
base.InitStyle(style);
|
||||
this.Background = style.ScrollBarBackground;
|
||||
this.ScrollerTexture = style.ScrollBarScrollerTexture;
|
||||
this.HoveredColor = style.ScrollBarHoveredColor;
|
||||
}
|
||||
|
||||
public delegate void ValueChanged(Element element, float value);
|
||||
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ using System.Text;
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using MLEM.Extensions;
|
||||
using MLEM.Font;
|
||||
using MLEM.Textures;
|
||||
using MLEM.Ui.Style;
|
||||
|
@ -67,7 +68,7 @@ namespace MLEM.Ui.Elements {
|
|||
this.caretBlinkTimer = 0;
|
||||
}
|
||||
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha) {
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, Point offset) {
|
||||
var tex = this.Texture;
|
||||
var color = Color.White * alpha;
|
||||
if (this.IsMouseOver) {
|
||||
|
@ -75,11 +76,11 @@ namespace MLEM.Ui.Elements {
|
|||
tex = this.HoveredTexture;
|
||||
color = this.HoveredColor * alpha;
|
||||
}
|
||||
batch.Draw(tex, this.DisplayArea, color, this.Scale);
|
||||
batch.Draw(tex, this.DisplayArea.OffsetCopy(offset), color, this.Scale);
|
||||
var caret = this.IsSelected && this.caretBlinkTimer >= 0.5F ? "|" : "";
|
||||
var text = this.Text.ToString(this.textStartIndex, this.Text.Length - this.textStartIndex) + caret;
|
||||
this.font.DrawCenteredString(batch, text, this.DisplayArea.Location.ToVector2() + new Vector2(this.TextOffsetX * this.Scale, this.DisplayArea.Height / 2), this.TextScale * this.Scale, Color.White * alpha, false, true);
|
||||
base.Draw(time, batch, alpha);
|
||||
this.font.DrawCenteredString(batch, text, this.DisplayArea.Location.ToVector2() + new Vector2(offset.X + this.TextOffsetX * this.Scale, offset.Y + this.DisplayArea.Height / 2), this.TextScale * this.Scale, Color.White * alpha, false, true);
|
||||
base.Draw(time, batch, alpha, offset);
|
||||
}
|
||||
|
||||
protected override void InitStyle(UiStyle style) {
|
||||
|
|
|
@ -12,6 +12,9 @@ namespace MLEM.Ui.Style {
|
|||
public NinePatch TextFieldTexture;
|
||||
public NinePatch TextFieldHoveredTexture;
|
||||
public Color TextFieldHoveredColor;
|
||||
public NinePatch ScrollBarBackground;
|
||||
public NinePatch ScrollBarScrollerTexture;
|
||||
public Color ScrollBarHoveredColor;
|
||||
public IGenericFont Font;
|
||||
public float TextScale = 1;
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@ namespace MLEM.Ui.Style {
|
|||
this.PanelTexture = GenerateTexture(batch, Color.Gray);
|
||||
this.TextFieldTexture = GenerateTexture(batch, Color.MediumBlue);
|
||||
this.TextFieldHoveredColor = Color.LightGray;
|
||||
this.ScrollBarBackground = GenerateTexture(batch, Color.LightBlue);
|
||||
this.ScrollBarScrollerTexture = GenerateTexture(batch, Color.Blue);
|
||||
this.ScrollBarHoveredColor = Color.LightGray;
|
||||
this.Font = new EmptyFont();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace MLEM.Ui {
|
|||
public class UiSystem {
|
||||
|
||||
public readonly GraphicsDevice GraphicsDevice;
|
||||
public Rectangle Viewport { get; private set; }
|
||||
private readonly List<RootElement> rootElements = new List<RootElement>();
|
||||
public readonly InputHandler InputHandler;
|
||||
private readonly bool isInputOurs;
|
||||
|
@ -47,8 +48,10 @@ namespace MLEM.Ui {
|
|||
this.InputHandler = inputHandler ?? new InputHandler();
|
||||
this.isInputOurs = inputHandler == null;
|
||||
this.style = style;
|
||||
this.Viewport = device.Viewport.Bounds;
|
||||
|
||||
window.ClientSizeChanged += (sender, args) => {
|
||||
this.Viewport = device.Viewport.Bounds;
|
||||
foreach (var root in this.rootElements)
|
||||
root.Element.ForceUpdateArea();
|
||||
};
|
||||
|
@ -92,16 +95,16 @@ namespace MLEM.Ui {
|
|||
|
||||
public void Draw(GameTime time, SpriteBatch batch) {
|
||||
foreach (var root in this.rootElements) {
|
||||
if (root.Element.IsHidden)
|
||||
continue;
|
||||
batch.Begin(SpriteSortMode.Deferred, this.BlendState, this.SamplerState);
|
||||
root.Element.Draw(time, batch, this.DrawAlpha * root.Element.DrawAlpha);
|
||||
batch.End();
|
||||
if (!root.Element.IsHidden)
|
||||
root.Element.DrawUnbound(time, batch, this.DrawAlpha * root.Element.DrawAlpha, this.BlendState, this.SamplerState);
|
||||
}
|
||||
|
||||
foreach (var root in this.rootElements) {
|
||||
if (!root.Element.IsHidden)
|
||||
root.Element.DrawUnbound(time, batch, this.DrawAlpha * root.Element.DrawAlpha, root.ActualScale, this.BlendState, this.SamplerState);
|
||||
if (root.Element.IsHidden)
|
||||
continue;
|
||||
batch.Begin(SpriteSortMode.Deferred, this.BlendState, this.SamplerState);
|
||||
root.Element.Draw(time, batch, this.DrawAlpha * root.Element.DrawAlpha, Point.Zero);
|
||||
batch.End();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,5 +28,11 @@ namespace MLEM.Extensions {
|
|||
return new Point((point.X * f).Floor(), (point.Y * f).Floor());
|
||||
}
|
||||
|
||||
public static Rectangle OffsetCopy(this Rectangle rect, Point offset) {
|
||||
rect.X += offset.X;
|
||||
rect.Y += offset.Y;
|
||||
return rect;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue