Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Rectangle a readonly struct. #21178

Merged
merged 2 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 5 additions & 6 deletions OpenRA.Game/Primitives/Rectangle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@

namespace OpenRA.Primitives
{
public struct Rectangle : IEquatable<Rectangle>
public readonly struct Rectangle : IEquatable<Rectangle>
{
// TODO: Make these readonly: this will require a lot of changes to the UI logic
public int X;
public int Y;
public int Width;
public int Height;
public readonly int X;
public readonly int Y;
public readonly int Width;
public readonly int Height;
public static readonly Rectangle Empty;

public static Rectangle FromLTRB(int left, int top, int right, int bottom)
Expand Down
36 changes: 29 additions & 7 deletions OpenRA.Game/Widgets/Widget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,28 @@ public class ChromeLogic : IDisposable
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;
Expand All @@ -201,7 +223,7 @@ public abstract class Widget
public bool IgnoreChildMouseOver;

// Calculated internally
public Rectangle Bounds;
public WidgetBounds Bounds;
public Widget Parent = null;
public Func<bool> IsVisible;

Expand Down Expand Up @@ -261,7 +283,7 @@ public virtual void Initialize(WidgetArgs args)

// 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) ?
Expand All @@ -276,15 +298,15 @@ public virtual void Initialize(WidgetArgs args)
substitutions.Add("PARENT_BOTTOM", parentBounds.Height);

var readOnlySubstitutions = new ReadOnlyDictionary<string, int>(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)
Expand Down
5 changes: 2 additions & 3 deletions OpenRA.Mods.Common/Widgets/BackgroundWidget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
*/
#endregion

using OpenRA.Primitives;
using OpenRA.Widgets;

namespace OpenRA.Mods.Common.Widgets
Expand Down Expand Up @@ -50,11 +49,11 @@ public override bool HandleMouseInput(MouseInput mi)
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;
}

Expand Down
5 changes: 2 additions & 3 deletions OpenRA.Mods.Common/Widgets/DropDownButtonWidget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Widgets;

namespace OpenRA.Mods.Common.Widgets
Expand Down Expand Up @@ -107,7 +106,7 @@ public void AttachPanel(Widget p, Action onCancel)
// 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(); };
Expand All @@ -129,7 +128,7 @@ public void AttachPanel(Widget p, Action onCancel)
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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Traits;
using OpenRA.Primitives;
using OpenRA.Widgets;

namespace OpenRA.Mods.Common.Widgets.Logic
Expand Down Expand Up @@ -501,7 +500,7 @@ static void RecalculateWidgetLayout(Widget w, bool insideScrollPanel = false)
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<string, int>
Expand All @@ -515,18 +514,18 @@ static void RecalculateWidgetLayout(Widget w, bool insideScrollPanel = false)
};

var readOnlySubstitutions = new ReadOnlyDictionary<string, int>(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);

Expand Down
5 changes: 2 additions & 3 deletions OpenRA.Mods.Common/Widgets/ScrollPanelWidget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,10 @@ public override void DrawOuter()

// 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();
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Widgets/SupportPowerTimerWidget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public override void Draw()
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);
Expand Down
8 changes: 4 additions & 4 deletions OpenRA.Mods.Common/Widgets/TextNotificationsDisplayWidget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,8 @@ public override void Initialize(WidgetArgs args)
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()
Expand All @@ -66,9 +65,10 @@ public override void DrawOuter()
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)
Expand Down