diff --git a/Demos/AnimationDemo.cs b/Demos/AnimationDemo.cs index 0ac4eb0..8e8d712 100644 --- a/Demos/AnimationDemo.cs +++ b/Demos/AnimationDemo.cs @@ -51,7 +51,7 @@ namespace Demos { this.group.Update(gameTime); } - protected override void Draw(GameTime gameTime) { + protected override void DoDraw(GameTime gameTime) { this.GraphicsDevice.Clear(Color.Black); this.SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, transformMatrix: Matrix.CreateScale(10)); @@ -60,7 +60,7 @@ namespace Demos { this.SpriteBatch.Draw(this.group.CurrentRegion, new Vector2(10, 10), Color.White); this.SpriteBatch.End(); - base.Draw(gameTime); + base.DoDraw(gameTime); } } diff --git a/Demos/AutoTilingDemo.cs b/Demos/AutoTilingDemo.cs index 5e36d79..37521c3 100644 --- a/Demos/AutoTilingDemo.cs +++ b/Demos/AutoTilingDemo.cs @@ -35,7 +35,7 @@ namespace Demos { }; } - protected override void Draw(GameTime gameTime) { + protected override void DoDraw(GameTime gameTime) { this.GraphicsDevice.Clear(Color.Black); // the texture region supplied to the AutoTiling method should only encompass the first filler tile's location and size @@ -49,7 +49,7 @@ namespace Demos { // don't draw non-grass tiles ( ) if (this.layout[y][x] != 'X') continue; - + var x1 = x; var y1 = y; // the connectsTo function determines for any given tile if it should connect to, that is, auto-tile with the @@ -67,7 +67,7 @@ namespace Demos { } this.SpriteBatch.End(); - base.Draw(gameTime); + base.DoDraw(gameTime); } } diff --git a/Demos/UiDemo.cs b/Demos/UiDemo.cs index 1ec1c52..e6d0f0f 100644 --- a/Demos/UiDemo.cs +++ b/Demos/UiDemo.cs @@ -17,6 +17,7 @@ namespace Demos { /// If using your own game class that derives from , however, you will have to do a few additional things to get MLEM.Ui up and running: /// - Create an instance of /// - Call the instance's Update method in your game's Update method + /// - Call the instance's DrawEarly method before clearing your /// - Call the instance's Draw method in your game's Draw method /// public class UiDemo : MlemGame { @@ -110,11 +111,21 @@ namespace Demos { root.AddChild(new VerticalSpace(3)); root.AddChild(new RadioButton(Anchor.AutoLeft, new Vector2(1, 10), "Radio button 1!")); root.AddChild(new RadioButton(Anchor.AutoLeft, new Vector2(1, 10), "Radio button 2!") {PositionOffset = new Vector2(0, 1)}); + + var tooltip = new Tooltip(50, "This is a test tooltip to see the window bounding") {IsHidden = true}; + this.UiSystem.Add("TestTooltip", tooltip); + root.AddChild(new VerticalSpace(3)); + root.AddChild(new Button(Anchor.AutoLeft, new Vector2(1, 10), "Toggle Test Tooltip") { + OnClicked = (element, button) => { + if (button == MouseButton.Left) + tooltip.IsHidden = !tooltip.IsHidden; + } + }); } - protected override void Draw(GameTime gameTime) { - this.GraphicsDevice.Clear(Color.Black); - base.Draw(gameTime); + protected override void DoDraw(GameTime gameTime) { + this.GraphicsDevice.Clear(Color.CornflowerBlue); + base.DoDraw(gameTime); } } diff --git a/MLEM.Startup/MlemGame.cs b/MLEM.Startup/MlemGame.cs index c2cac4c..95861c9 100644 --- a/MLEM.Startup/MlemGame.cs +++ b/MLEM.Startup/MlemGame.cs @@ -60,11 +60,16 @@ namespace MLEM.Startup { } protected override void Draw(GameTime gameTime) { - base.Draw(gameTime); + this.UiSystem.DrawEarly(gameTime, this.SpriteBatch); + this.DoDraw(gameTime); this.UiSystem.Draw(gameTime, this.SpriteBatch); CoroutineHandler.RaiseEvent(CoroutineEvents.Draw); } + protected virtual void DoDraw(GameTime gameTime) { + base.Draw(gameTime); + } + public static T LoadContent(string name) { return instance.Content.Load(name); } diff --git a/MLEM.Ui/Elements/Element.cs b/MLEM.Ui/Elements/Element.cs index d4515e3..dd6cd43 100644 --- a/MLEM.Ui/Elements/Element.cs +++ b/MLEM.Ui/Elements/Element.cs @@ -218,6 +218,8 @@ namespace MLEM.Ui.Elements { public virtual void ForceUpdateArea() { this.areaDirty = false; + if (this.IsHidden) + return; var parentArea = this.Parent != null ? this.Parent.ChildPaddedArea : this.system.Viewport; var parentCenterX = parentArea.X + parentArea.Width / 2; @@ -361,10 +363,10 @@ namespace MLEM.Ui.Elements { } } - public virtual void DrawUnbound(GameTime time, SpriteBatch batch, float alpha, BlendState blendState = null, SamplerState samplerState = null) { + public virtual void DrawEarly(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, blendState, samplerState); + child.DrawEarly(time, batch, alpha * child.DrawAlpha, blendState, samplerState); } } diff --git a/MLEM.Ui/Elements/Panel.cs b/MLEM.Ui/Elements/Panel.cs index 69ff37f..6470720 100644 --- a/MLEM.Ui/Elements/Panel.cs +++ b/MLEM.Ui/Elements/Panel.cs @@ -91,7 +91,7 @@ namespace MLEM.Ui.Elements { } } - public override void DrawUnbound(GameTime time, SpriteBatch batch, float alpha, BlendState blendState = null, SamplerState samplerState = null) { + public override void DrawEarly(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); @@ -103,7 +103,7 @@ namespace MLEM.Ui.Elements { batch.End(); batch.GraphicsDevice.SetRenderTarget(null); } - base.DrawUnbound(time, batch, alpha, blendState, samplerState); + base.DrawEarly(time, batch, alpha, blendState, samplerState); } private Rectangle GetRenderTargetArea() { diff --git a/MLEM.Ui/Elements/Paragraph.cs b/MLEM.Ui/Elements/Paragraph.cs index 5a4ee21..576f88f 100644 --- a/MLEM.Ui/Elements/Paragraph.cs +++ b/MLEM.Ui/Elements/Paragraph.cs @@ -29,6 +29,7 @@ namespace MLEM.Ui.Elements { this.SetAreaDirty(); } } + public bool AutoAdjustWidth; public Paragraph(Anchor anchor, float width, string text, bool centerText = false, IGenericFont font = null) : base(anchor, new Vector2(width, 0)) { this.text = text; @@ -39,7 +40,7 @@ namespace MLEM.Ui.Elements { protected override Point CalcActualSize(Rectangle parentArea) { var size = base.CalcActualSize(parentArea); - this.splitText = this.font.SplitString(this.text, size.X, this.TextScale * this.Scale).ToArray(); + this.splitText = this.font.SplitString(this.text, size.X - this.ScaledPadding.X * 2, this.TextScale * this.Scale).ToArray(); this.lineHeight = 0; this.longestLineLength = 0; @@ -52,14 +53,12 @@ namespace MLEM.Ui.Elements { if (strgScale.X > this.longestLineLength) this.longestLineLength = strgScale.X; } - return new Point(size.X, height.Ceil()); + return new Point(this.AutoAdjustWidth ? (this.longestLineLength + this.ScaledPadding.X * 2).Ceil() : size.X, height.Ceil() + this.ScaledPadding.Y * 2); } public override void Draw(GameTime time, SpriteBatch batch, float alpha, Point offset) { - if (this.Background != null) { - var backgroundArea = new Rectangle(this.Area.X + offset.X, this.Area.Y + offset.Y, this.longestLineLength.Ceil() + this.ScaledPadding.X * 2, this.Area.Height + this.ScaledPadding.Y * 2); - batch.Draw(this.Background, backgroundArea, this.BackgroundColor * alpha); - } + if (this.Background != null) + batch.Draw(this.Background, this.Area.OffsetCopy(offset), this.BackgroundColor * alpha); var pos = this.DisplayArea.Location.ToVector2(); var off = offset.ToVector2(); diff --git a/MLEM.Ui/Elements/Tooltip.cs b/MLEM.Ui/Elements/Tooltip.cs index ff6a21c..2918669 100644 --- a/MLEM.Ui/Elements/Tooltip.cs +++ b/MLEM.Ui/Elements/Tooltip.cs @@ -11,12 +11,24 @@ namespace MLEM.Ui.Elements { public Tooltip(float width, string text, IGenericFont font = null) : base(Anchor.TopLeft, width, text, false, font) { + this.AutoAdjustWidth = true; this.Padding = new Point(2); } public override void Update(GameTime time) { base.Update(time); - this.PositionOffset = this.MousePos.ToVector2() / this.Scale + this.MouseOffset; + + var viewport = this.System.Viewport.Size; + var offset = this.MousePos.ToVector2() / this.Scale + this.MouseOffset; + if (offset.X < 0) + offset.X = 0; + if (offset.Y < 0) + offset.Y = 0; + if (offset.X * this.Scale + this.Area.Width >= viewport.X) + offset.X = (viewport.X - this.Area.Width) / this.Scale; + if (offset.Y * this.Scale + this.Area.Height >= viewport.Y) + offset.Y = (viewport.Y - this.Area.Height) / this.Scale; + this.PositionOffset = offset; } public override void ForceUpdateArea() { diff --git a/MLEM.Ui/UiSystem.cs b/MLEM.Ui/UiSystem.cs index 35fbd2d..f623750 100644 --- a/MLEM.Ui/UiSystem.cs +++ b/MLEM.Ui/UiSystem.cs @@ -93,12 +93,14 @@ namespace MLEM.Ui { root.Element.Update(time); } - public void Draw(GameTime time, SpriteBatch batch) { + public void DrawEarly(GameTime time, SpriteBatch batch) { 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.DrawEarly(time, batch, this.DrawAlpha * root.Element.DrawAlpha, this.BlendState, this.SamplerState); } + } + public void Draw(GameTime time, SpriteBatch batch) { foreach (var root in this.rootElements) { if (root.Element.IsHidden) continue; diff --git a/MLEM/Extensions/NumberExtensions.cs b/MLEM/Extensions/NumberExtensions.cs index b627d2b..237f8c0 100644 --- a/MLEM/Extensions/NumberExtensions.cs +++ b/MLEM/Extensions/NumberExtensions.cs @@ -28,6 +28,10 @@ namespace MLEM.Extensions { return new Point((point.X * f).Floor(), (point.Y * f).Floor()); } + public static Point Divide(this Point point, float f) { + 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;