diff --git a/OpenRA.Game/Widgets/Widget.cs b/OpenRA.Game/Widgets/Widget.cs index 7aeac493f9..35b9f2eca9 100644 --- a/OpenRA.Game/Widgets/Widget.cs +++ b/OpenRA.Game/Widgets/Widget.cs @@ -182,6 +182,28 @@ namespace OpenRA.Widgets protected virtual void Dispose(bool disposing) { } } + public struct WidgetBounds + { + public int X, Y, Width, Height; + public readonly int Left => X; + public readonly int Right => X + Width; + public readonly int Top => Y; + public readonly int Bottom => Y + Height; + + public WidgetBounds(int x, int y, int width, int height) + { + X = x; + Y = y; + Width = width; + Height = height; + } + + public readonly Rectangle ToRectangle() + { + return new Rectangle(X, Y, Width, Height); + } + } + public abstract class Widget { string defaultCursor = null; @@ -201,7 +223,7 @@ namespace OpenRA.Widgets public bool IgnoreChildMouseOver; // Calculated internally - public Rectangle Bounds; + public WidgetBounds Bounds; public Widget Parent = null; public Func IsVisible; @@ -261,7 +283,7 @@ namespace OpenRA.Widgets // Parse the YAML equations to find the widget bounds var parentBounds = (Parent == null) - ? new Rectangle(0, 0, Game.Renderer.Resolution.Width, Game.Renderer.Resolution.Height) + ? new WidgetBounds(0, 0, Game.Renderer.Resolution.Width, Game.Renderer.Resolution.Height) : Parent.Bounds; var substitutions = args.TryGetValue("substitutions", out var subs) ? @@ -276,15 +298,15 @@ namespace OpenRA.Widgets substitutions.Add("PARENT_BOTTOM", parentBounds.Height); var readOnlySubstitutions = new ReadOnlyDictionary(substitutions); - var width = Width != null ? Width.Evaluate(readOnlySubstitutions) : 0; - var height = Height != null ? Height.Evaluate(readOnlySubstitutions) : 0; + var width = Width?.Evaluate(readOnlySubstitutions) ?? 0; + var height = Height?.Evaluate(readOnlySubstitutions) ?? 0; substitutions.Add("WIDTH", width); substitutions.Add("HEIGHT", height); - var x = X != null ? X.Evaluate(readOnlySubstitutions) : 0; - var y = Y != null ? Y.Evaluate(readOnlySubstitutions) : 0; - Bounds = new Rectangle(x, y, width, height); + var x = X?.Evaluate(readOnlySubstitutions) ?? 0; + var y = Y?.Evaluate(readOnlySubstitutions) ?? 0; + Bounds = new WidgetBounds(x, y, width, height); } public void PostInit(WidgetArgs args) diff --git a/OpenRA.Mods.Common/Widgets/BackgroundWidget.cs b/OpenRA.Mods.Common/Widgets/BackgroundWidget.cs index 961c31d90c..e644e08e90 100644 --- a/OpenRA.Mods.Common/Widgets/BackgroundWidget.cs +++ b/OpenRA.Mods.Common/Widgets/BackgroundWidget.cs @@ -9,7 +9,6 @@ */ #endregion -using OpenRA.Primitives; using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets @@ -50,11 +49,11 @@ namespace OpenRA.Mods.Common.Widgets break; case MouseInputEvent.Down: moving = true; - Bounds = new Rectangle(Bounds.X + vec.X, Bounds.Y + vec.Y, Bounds.Width, Bounds.Height); + Bounds = new WidgetBounds(Bounds.X + vec.X, Bounds.Y + vec.Y, Bounds.Width, Bounds.Height); break; case MouseInputEvent.Move: if (moving) - Bounds = new Rectangle(Bounds.X + vec.X, Bounds.Y + vec.Y, Bounds.Width, Bounds.Height); + Bounds = new WidgetBounds(Bounds.X + vec.X, Bounds.Y + vec.Y, Bounds.Width, Bounds.Height); break; } diff --git a/OpenRA.Mods.Common/Widgets/DropDownButtonWidget.cs b/OpenRA.Mods.Common/Widgets/DropDownButtonWidget.cs index 58c5c90be4..36e74c8c5b 100644 --- a/OpenRA.Mods.Common/Widgets/DropDownButtonWidget.cs +++ b/OpenRA.Mods.Common/Widgets/DropDownButtonWidget.cs @@ -13,7 +13,6 @@ using System; using System.Collections.Generic; using System.Linq; using OpenRA.Graphics; -using OpenRA.Primitives; using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets @@ -107,7 +106,7 @@ namespace OpenRA.Mods.Common.Widgets // Mask to prevent any clicks from being sent to other widgets fullscreenMask = new MaskWidget { - Bounds = new Rectangle(0, 0, Game.Renderer.Resolution.Width, Game.Renderer.Resolution.Height) + Bounds = new WidgetBounds(0, 0, Game.Renderer.Resolution.Width, Game.Renderer.Resolution.Height) }; fullscreenMask.OnMouseDown += mi => { Game.Sound.PlayNotification(ModRules, null, "Sounds", ClickSound, null); RemovePanel(); }; @@ -129,7 +128,7 @@ namespace OpenRA.Mods.Common.Widgets if (panelY + oldBounds.Height > Game.Renderer.Resolution.Height) panelY -= Bounds.Height + oldBounds.Height; - panel.Bounds = new Rectangle( + panel.Bounds = new WidgetBounds( panelX, panelY, oldBounds.Width, diff --git a/OpenRA.Mods.Common/Widgets/Logic/Settings/DisplaySettingsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Settings/DisplaySettingsLogic.cs index e755573c90..dab17c87ce 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Settings/DisplaySettingsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Settings/DisplaySettingsLogic.cs @@ -16,7 +16,6 @@ using System.Globalization; using System.Linq; using OpenRA.Graphics; using OpenRA.Mods.Common.Traits; -using OpenRA.Primitives; using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets.Logic @@ -501,7 +500,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic return; var parentBounds = w.Parent == null - ? new Rectangle(0, 0, Game.Renderer.Resolution.Width, Game.Renderer.Resolution.Height) + ? new WidgetBounds(0, 0, Game.Renderer.Resolution.Width, Game.Renderer.Resolution.Height) : w.Parent.Bounds; var substitutions = new Dictionary @@ -515,18 +514,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic }; var readOnlySubstitutions = new ReadOnlyDictionary(substitutions); - var width = w.Width != null ? w.Width.Evaluate(readOnlySubstitutions) : 0; - var height = w.Height != null ? w.Height.Evaluate(readOnlySubstitutions) : 0; + var width = w.Width?.Evaluate(readOnlySubstitutions) ?? 0; + var height = w.Height?.Evaluate(readOnlySubstitutions) ?? 0; substitutions.Add("WIDTH", width); substitutions.Add("HEIGHT", height); if (insideScrollPanel) - w.Bounds = new Rectangle(w.Bounds.X, w.Bounds.Y, width, w.Bounds.Height); + w.Bounds = new WidgetBounds(w.Bounds.X, w.Bounds.Y, width, w.Bounds.Height); else - w.Bounds = new Rectangle( - w.X != null ? w.X.Evaluate(readOnlySubstitutions) : 0, - w.Y != null ? w.Y.Evaluate(readOnlySubstitutions) : 0, + w.Bounds = new WidgetBounds( + w.X?.Evaluate(readOnlySubstitutions) ?? 0, + w.Y?.Evaluate(readOnlySubstitutions) ?? 0, width, height); diff --git a/OpenRA.Mods.Common/Widgets/ScrollPanelWidget.cs b/OpenRA.Mods.Common/Widgets/ScrollPanelWidget.cs index 07738edb88..6ffc5dc972 100644 --- a/OpenRA.Mods.Common/Widgets/ScrollPanelWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ScrollPanelWidget.cs @@ -225,11 +225,10 @@ namespace OpenRA.Mods.Common.Widgets // ChildOrigin enumerates the widget tree, so only evaluate it once var co = ChildOrigin; - drawBounds.X -= co.X; - drawBounds.Y -= co.Y; + drawBounds = new Rectangle(drawBounds.X - co.X, drawBounds.Y - co.Y, drawBounds.Width, drawBounds.Height); foreach (var child in Children) - if (child.Bounds.IntersectsWith(drawBounds)) + if (child.Bounds.ToRectangle().IntersectsWith(drawBounds)) child.DrawOuter(); Game.Renderer.DisableScissor(); diff --git a/OpenRA.Mods.Common/Widgets/SupportPowerTimerWidget.cs b/OpenRA.Mods.Common/Widgets/SupportPowerTimerWidget.cs index e3517777b5..7a2b5a2616 100644 --- a/OpenRA.Mods.Common/Widgets/SupportPowerTimerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/SupportPowerTimerWidget.cs @@ -78,7 +78,7 @@ namespace OpenRA.Mods.Common.Widgets foreach (var t in texts) { var textSize = font.Measure(t.Text); - var location = new float2(Bounds.Location) + new float2(0, y); + var location = new float2(Bounds.X, Bounds.Y + y); if (Align == TextAlign.Center) location += new int2((Bounds.Width - textSize.X) / 2, 0); diff --git a/OpenRA.Mods.Common/Widgets/TextNotificationsDisplayWidget.cs b/OpenRA.Mods.Common/Widgets/TextNotificationsDisplayWidget.cs index 20f308b718..f9e03cae9e 100644 --- a/OpenRA.Mods.Common/Widgets/TextNotificationsDisplayWidget.cs +++ b/OpenRA.Mods.Common/Widgets/TextNotificationsDisplayWidget.cs @@ -51,9 +51,8 @@ namespace OpenRA.Mods.Common.Widgets var wholeLines = (int)Math.Floor((double)((Bounds.Height - BottomSpacing) / lineHeight)); var visibleChildrenHeight = wholeLines * lineHeight; - overflowDrawBounds = new Rectangle(RenderOrigin.X, RenderOrigin.Y, Bounds.Width, Bounds.Height); - overflowDrawBounds.Y += Bounds.Height - visibleChildrenHeight; - overflowDrawBounds.Height = visibleChildrenHeight; + var y = RenderOrigin.Y + Bounds.Height - visibleChildrenHeight; + overflowDrawBounds = new Rectangle(RenderOrigin.X, y, Bounds.Width, visibleChildrenHeight); } public override void DrawOuter() @@ -66,9 +65,10 @@ namespace OpenRA.Mods.Common.Widgets if (mostRecentMessageOverflows && HideOverflow) Game.Renderer.EnableScissor(overflowDrawBounds); + var bounds = Bounds.ToRectangle(); for (var i = Children.Count - 1; i >= 0; i--) { - if (Bounds.Contains(Children[i].Bounds) || !HideOverflow || mostRecentMessageOverflows) + if (!HideOverflow || mostRecentMessageOverflows || bounds.Contains(Children[i].Bounds.ToRectangle())) Children[i].DrawOuter(); if (mostRecentMessageOverflows)