Introduce IMouseBounds and split/rework mouse rectangles.
The render bounds for an actor now include the area covered by bibs, shadows, and any other widgets. In many cases this area is much larger than we really want to consider for tooltips and mouse selection. An optional Margin is added to Selectable to support cases like infantry, where we want the mouse area of the actor to be larger than the drawn selection box.
This commit is contained in:
@@ -9,6 +9,10 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
[Desc("This actor is selectable. Defines bounds of selectable area, selection class and selection priority.")]
|
||||
@@ -19,6 +23,9 @@ namespace OpenRA.Traits
|
||||
[Desc("Bounds for the selectable area.")]
|
||||
public readonly int[] Bounds = null;
|
||||
|
||||
[Desc("Area outside the visible selection box that is enabled for selection")]
|
||||
public readonly int Margin = 0;
|
||||
|
||||
[Desc("All units having the same selection class specified will be selected with select-by-type commands (e.g. double-click). "
|
||||
+ "Defaults to the actor name when not defined or inherited.")]
|
||||
public readonly string Class = null;
|
||||
@@ -28,7 +35,7 @@ namespace OpenRA.Traits
|
||||
public object Create(ActorInitializer init) { return new Selectable(init.Self, this); }
|
||||
}
|
||||
|
||||
public class Selectable
|
||||
public class Selectable : IMouseBounds
|
||||
{
|
||||
public readonly string Class = null;
|
||||
|
||||
@@ -39,5 +46,20 @@ namespace OpenRA.Traits
|
||||
Class = string.IsNullOrEmpty(info.Class) ? self.Info.Name : info.Class;
|
||||
Info = info;
|
||||
}
|
||||
|
||||
Rectangle IMouseBounds.MouseoverBounds(Actor self, WorldRenderer wr)
|
||||
{
|
||||
if (Info.Bounds == null)
|
||||
return Rectangle.Empty;
|
||||
|
||||
var size = new int2(Info.Bounds[0], Info.Bounds[1]);
|
||||
|
||||
var offset = -size / 2 - new int2(Info.Margin, Info.Margin);
|
||||
if (Info.Bounds.Length > 2)
|
||||
offset += new int2(Info.Bounds[2], Info.Bounds[3]);
|
||||
|
||||
var xy = wr.ScreenPxPosition(self.CenterPosition) + offset;
|
||||
return new Rectangle(xy.X, xy.Y, size.X + 2 * Info.Margin, size.Y + 2 * Info.Margin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user