diff --git a/MLEM.Ui/Elements/Button.cs b/MLEM.Ui/Elements/Button.cs index 92de86a..0589d9f 100644 --- a/MLEM.Ui/Elements/Button.cs +++ b/MLEM.Ui/Elements/Button.cs @@ -22,7 +22,7 @@ namespace MLEM.Ui.Elements { this.Tooltip = new Tooltip(tooltipWidth, tooltipText, this); } - public override void Draw(GameTime time, SpriteBatch batch, float alpha) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { var tex = this.Texture; var color = Color.White * alpha; if (this.IsMouseOver) { @@ -31,7 +31,7 @@ namespace MLEM.Ui.Elements { color = this.HoveredColor * alpha; } batch.Draw(tex, this.DisplayArea, color, this.Scale); - base.Draw(time, batch, alpha); + base.Draw(time, batch, alpha, blendState, samplerState, matrix); } protected override void InitStyle(UiStyle style) { diff --git a/MLEM.Ui/Elements/Checkbox.cs b/MLEM.Ui/Elements/Checkbox.cs index c1ddf0a..773afbf 100644 --- a/MLEM.Ui/Elements/Checkbox.cs +++ b/MLEM.Ui/Elements/Checkbox.cs @@ -46,7 +46,7 @@ namespace MLEM.Ui.Elements { return size; } - public override void Draw(GameTime time, SpriteBatch batch, float alpha) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { var tex = this.Texture; var color = Color.White * alpha; if (this.IsMouseOver) { @@ -59,7 +59,7 @@ namespace MLEM.Ui.Elements { batch.Draw(tex, boxDisplayArea, color, this.Scale); if (this.Checked) batch.Draw(this.Checkmark, boxDisplayArea, Color.White * alpha); - base.Draw(time, batch, alpha); + base.Draw(time, batch, alpha, blendState, samplerState, matrix); } protected override void InitStyle(UiStyle style) { diff --git a/MLEM.Ui/Elements/CustomDrawGroup.cs b/MLEM.Ui/Elements/CustomDrawGroup.cs index 98296f8..1d590c9 100644 --- a/MLEM.Ui/Elements/CustomDrawGroup.cs +++ b/MLEM.Ui/Elements/CustomDrawGroup.cs @@ -15,17 +15,17 @@ namespace MLEM.Ui.Elements { public delegate void BeginDelegate(CustomDrawGroup element, GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix); - public override void Draw(GameTime time, SpriteBatch batch, float alpha) { - // this is left empty because child components are drawn in DrawEarly - } - - public override void DrawEarly(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { + // end the usual draw so that we can begin our own + batch.End(); var mat = matrix * this.Transform; this.BeginImpl(this, time, batch, alpha, blendState, samplerState, mat); // draw child components in custom begin call - base.Draw(time, batch, alpha); + base.Draw(time, batch, alpha, blendState, samplerState, mat); + // end our draw batch.End(); - base.DrawEarly(time, batch, alpha, blendState, samplerState, mat); + // begin the usual draw again for other elements + batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, null, null, null, matrix); } } diff --git a/MLEM.Ui/Elements/Element.cs b/MLEM.Ui/Elements/Element.cs index 619c053..627e8da 100644 --- a/MLEM.Ui/Elements/Element.cs +++ b/MLEM.Ui/Elements/Element.cs @@ -420,16 +420,13 @@ 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, BlendState blendState, SamplerState samplerState, Matrix matrix) { this.System.OnElementDrawn?.Invoke(this, time, batch, alpha); foreach (var child in this.SortedChildren) { if (!child.IsHidden) - child.Draw(time, batch, alpha * child.DrawAlpha); + child.Draw(time, batch, alpha * child.DrawAlpha, blendState, samplerState, matrix); } - - if (this.IsSelected) - this.System.OnSelectedElementDrawn?.Invoke(this, time, batch, alpha); } public virtual void DrawEarly(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { diff --git a/MLEM.Ui/Elements/Image.cs b/MLEM.Ui/Elements/Image.cs index c1d2036..9532680 100644 --- a/MLEM.Ui/Elements/Image.cs +++ b/MLEM.Ui/Elements/Image.cs @@ -46,7 +46,7 @@ namespace MLEM.Ui.Elements { return this.texture != null && this.scaleToImage ? this.texture.Size : base.CalcActualSize(parentArea); } - public override void Draw(GameTime time, SpriteBatch batch, float alpha) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { var center = new Vector2(this.texture.Width / 2F, this.texture.Height / 2F); if (this.MaintainImageAspect) { var scale = Math.Min(this.DisplayArea.Width / (float) this.texture.Width, this.DisplayArea.Height / (float) this.texture.Height); @@ -56,7 +56,7 @@ namespace MLEM.Ui.Elements { var scale = new Vector2(1F / this.texture.Width, 1F / this.texture.Height) * this.DisplayArea.Size.ToVector2(); batch.Draw(this.texture, this.DisplayArea.Location.ToVector2() + center * scale, this.Color * alpha, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0); } - base.Draw(time, batch, alpha); + base.Draw(time, batch, alpha, blendState, samplerState, matrix); } } diff --git a/MLEM.Ui/Elements/Panel.cs b/MLEM.Ui/Elements/Panel.cs index c874d7f..bf87803 100644 --- a/MLEM.Ui/Elements/Panel.cs +++ b/MLEM.Ui/Elements/Panel.cs @@ -92,11 +92,11 @@ namespace MLEM.Ui.Elements { child.ScrollOffset = new Point(0, offset); } - public override void Draw(GameTime time, SpriteBatch batch, float alpha) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { batch.Draw(this.Texture, this.DisplayArea, Color.White * alpha, this.Scale); // if we handle overflow, draw using the render target in DrawUnbound if (!this.scrollOverflow) { - base.Draw(time, batch, alpha); + base.Draw(time, batch, alpha, blendState, samplerState, matrix); } else if (this.renderTarget != null) { // 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(), Color.White); @@ -113,7 +113,7 @@ namespace MLEM.Ui.Elements { var trans = Matrix.CreateTranslation(-area.X, -area.Y, 0); // do the usual draw, but within the render target batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, null, null, null, trans); - base.Draw(time, batch, alpha); + base.Draw(time, batch, alpha, blendState, samplerState, trans); batch.End(); // also draw any children early within the render target with the translation applied base.DrawEarly(time, batch, alpha, blendState, samplerState, trans); diff --git a/MLEM.Ui/Elements/Paragraph.cs b/MLEM.Ui/Elements/Paragraph.cs index 0fac150..380d880 100644 --- a/MLEM.Ui/Elements/Paragraph.cs +++ b/MLEM.Ui/Elements/Paragraph.cs @@ -69,7 +69,7 @@ namespace MLEM.Ui.Elements { this.TimeIntoAnimation += time.ElapsedGameTime; } - public override void Draw(GameTime time, SpriteBatch batch, float alpha) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { if (this.Background != null) batch.Draw(this.Background, this.Area, this.BackgroundColor * alpha); @@ -83,7 +83,7 @@ namespace MLEM.Ui.Elements { // if we have formatting codes, we should do it this.regularFont.DrawFormattedString(batch, pos, this.splitText, this.codeLocations, this.TextColor * alpha, sc, this.boldFont, this.italicFont, 0, this.TimeIntoAnimation); } - base.Draw(time, batch, alpha); + base.Draw(time, batch, alpha, blendState, samplerState, matrix); } protected override void InitStyle(UiStyle style) { diff --git a/MLEM.Ui/Elements/ProgressBar.cs b/MLEM.Ui/Elements/ProgressBar.cs index d0ab302..4bb8f3f 100644 --- a/MLEM.Ui/Elements/ProgressBar.cs +++ b/MLEM.Ui/Elements/ProgressBar.cs @@ -32,7 +32,7 @@ namespace MLEM.Ui.Elements { this.CanBeSelected = false; } - public override void Draw(GameTime time, SpriteBatch batch, float alpha) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { batch.Draw(this.Texture, this.DisplayArea, this.Color * alpha, this.Scale); var percentage = this.CurrentValue / this.MaxValue; @@ -63,7 +63,7 @@ namespace MLEM.Ui.Elements { } else { batch.Draw(batch.GetBlankTexture(), offsetArea, this.ProgressColor * alpha); } - base.Draw(time, batch, alpha); + base.Draw(time, batch, alpha, blendState, samplerState, matrix); } protected override void InitStyle(UiStyle style) { diff --git a/MLEM.Ui/Elements/ScrollBar.cs b/MLEM.Ui/Elements/ScrollBar.cs index 012fa16..e00feb8 100644 --- a/MLEM.Ui/Elements/ScrollBar.cs +++ b/MLEM.Ui/Elements/ScrollBar.cs @@ -118,7 +118,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, BlendState blendState, SamplerState samplerState, Matrix matrix) { batch.Draw(this.Background, this.DisplayArea, Color.White * alpha, this.Scale); var scrollerPos = new Point(this.DisplayArea.X + this.ScrollerOffset.X, this.DisplayArea.Y + this.ScrollerOffset.Y); @@ -127,7 +127,7 @@ namespace MLEM.Ui.Elements { this.Horizontal ? 0 : (this.currValue / this.maxValue * (this.DisplayArea.Height - this.ScrollerSize.Y * this.Scale)).Floor()); var scrollerRect = new Rectangle(scrollerPos + scrollerOffset, new Point((this.ScrollerSize.X * this.Scale).Ceil(), (this.ScrollerSize.Y * this.Scale).Ceil())); batch.Draw(this.ScrollerTexture, scrollerRect, Color.White * alpha, this.Scale); - base.Draw(time, batch, alpha); + base.Draw(time, batch, alpha, blendState, samplerState, matrix); } protected override void InitStyle(UiStyle style) { diff --git a/MLEM.Ui/Elements/TextField.cs b/MLEM.Ui/Elements/TextField.cs index 932bbe1..3d154fd 100644 --- a/MLEM.Ui/Elements/TextField.cs +++ b/MLEM.Ui/Elements/TextField.cs @@ -132,7 +132,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, BlendState blendState, SamplerState samplerState, Matrix matrix) { var tex = this.Texture; var color = Color.White * alpha; if (this.IsMouseOver) { @@ -150,7 +150,7 @@ namespace MLEM.Ui.Elements { } else if (this.PlaceholderText != null) { this.font.DrawCenteredString(batch, this.PlaceholderText, textPos, this.TextScale * this.Scale, Color.Gray * alpha, false, true); } - base.Draw(time, batch, alpha); + base.Draw(time, batch, alpha, blendState, samplerState, matrix); } public void SetText(object text, bool removeMismatching = false) { diff --git a/MLEM.Ui/UiSystem.cs b/MLEM.Ui/UiSystem.cs index 5ada373..27a7df6 100644 --- a/MLEM.Ui/UiSystem.cs +++ b/MLEM.Ui/UiSystem.cs @@ -111,7 +111,10 @@ namespace MLEM.Ui { if (root.Element.IsHidden) continue; batch.Begin(SpriteSortMode.Deferred, this.BlendState, this.SamplerState, null, null, null, root.Transform); - root.Element.Draw(time, batch, this.DrawAlpha * root.Element.DrawAlpha); + var alpha = this.DrawAlpha * root.Element.DrawAlpha; + root.Element.Draw(time, batch, alpha, this.BlendState, this.SamplerState, root.Transform); + if (root.SelectedElement != null) + this.OnSelectedElementDrawn?.Invoke(root.SelectedElement, time, batch, alpha); batch.End(); } } diff --git a/Sandbox/Content/Content.mgcb b/Sandbox/Content/Content.mgcb index 60ef567..635a3e0 100644 --- a/Sandbox/Content/Content.mgcb +++ b/Sandbox/Content/Content.mgcb @@ -24,3 +24,22 @@ /processor:TiledMapTilesetProcessor /build:Tiled/Tileset.tsx +#begin Textures/Test.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/Test.png + +#begin Fonts/TestFont.spritefont +/importer:FontDescriptionImporter +/processor:FontDescriptionProcessor +/processorParam:PremultiplyAlpha=True +/processorParam:TextureFormat=Compressed +/build:Fonts/TestFont.spritefont + diff --git a/Sandbox/Content/Fonts/TestFont.spritefont b/Sandbox/Content/Fonts/TestFont.spritefont new file mode 100644 index 0000000..54ab9ac --- /dev/null +++ b/Sandbox/Content/Fonts/TestFont.spritefont @@ -0,0 +1,60 @@ + + + + + + + Arial + + + 32 + + + 0 + + + true + + + + + + * + + + + + + ɏ + + + + diff --git a/Sandbox/Content/Textures/Test.png b/Sandbox/Content/Textures/Test.png new file mode 100644 index 0000000..7d88c33 Binary files /dev/null and b/Sandbox/Content/Textures/Test.png differ diff --git a/Sandbox/GameImpl.cs b/Sandbox/GameImpl.cs index 150725c..974c91c 100644 --- a/Sandbox/GameImpl.cs +++ b/Sandbox/GameImpl.cs @@ -3,7 +3,12 @@ using Microsoft.Xna.Framework.Graphics; using MLEM.Cameras; using MLEM.Extended.Extensions; using MLEM.Extended.Tiled; +using MLEM.Font; using MLEM.Startup; +using MLEM.Textures; +using MLEM.Ui; +using MLEM.Ui.Elements; +using MLEM.Ui.Style; using MonoGame.Extended.Tiled; namespace Sandbox { @@ -28,6 +33,22 @@ namespace Sandbox { Scale = 2, LookingPosition = new Vector2(25, 25) * this.map.GetTileSize() }; + + var tex = LoadContent("Textures/Test"); + this.UiSystem.Style = new UntexturedStyle(this.SpriteBatch) { + Font = new GenericSpriteFont(LoadContent("Fonts/TestFont")), + TextScale = 0.1F, + PanelTexture = new NinePatch(new TextureRegion(tex, 0, 8, 24, 24), 8), + ButtonTexture = new NinePatch(new TextureRegion(tex, 24, 8, 16, 16), 4) + }; + this.UiSystem.AutoScaleReferenceSize = new Point(1280, 720); + this.UiSystem.AutoScaleWithScreen = true; + this.UiSystem.GlobalScale = 5; + + var root = new Panel(Anchor.Center, new Vector2(50, 50), Vector2.Zero); + this.UiSystem.Add("Root", root); + var group = root.AddChild(new CustomDrawGroup(Anchor.AutoLeft, new Vector2(1, 10))); + group.AddChild(new Button(Anchor.AutoLeft, Vector2.One, "Test text")); } protected override void DoDraw(GameTime gameTime) {