Class UIElement
The base of every control in a view. Subclasses are the controls the view file
names, such as Label and Button.
public abstract class UIElement : DrawableComponent, IUpdateable, IEquatable<IUpdateable>, IDrawable, IIdentifiable<Guid>, IEquatable<IDrawable>, IDisposable
- Inheritance
-
UIElement
- Implements
- Derived
- Inherited Members
Constructors
UIElement(ILogger, View, string)
Creates a control in view. A null id gives the
control a generated ControlId.
protected UIElement(ILogger logger, View view, string id = null)
Parameters
Properties
BorderColor
The colour of the border drawn around the control, or null for none.
public Color? BorderColor { get; set; }
Property Value
BorderThickness
The border's width in pixels. A border is drawn only when this is above 0 and BorderColor is set.
public int BorderThickness { get; set; }
Property Value
Bounds
The rectangle the control occupies: Location and Size. A control can override this to include something it draws beyond that rectangle.
public virtual Rectangle Bounds { get; }
Property Value
ControlId
The control's name: the view's Id, or a generated GUID when the view gave none.
public string ControlId { get; }
Property Value
DeclaredSize
The width and height the view declared for this control, per axis; null for an axis the view left unset. Unlike Size, layout does not change it.
public Vector2? DeclaredSize { get; set; }
Property Value
Disabled
Whether the control is switched off. A disabled control does not respond to input. Use IsEffectivelyDisabled to include a disabled container above it.
public bool Disabled { get; set; }
Property Value
FillColor
A flat colour drawn behind the control, or null for none. It is drawn over Bounds, so it needs no texture.
public Color? FillColor { get; set; }
Property Value
FillGradient
A gradient fill, drawn in place of FillColor when both are set. Null for none.
public Gradient FillGradient { get; set; }
Property Value
FillMesh
The tessellated fill, for a control that paints it over something other than its own whole Bounds - a progress bar filling the left portion of its track.
protected GradientMesh FillMesh { get; }
Property Value
GlobalBounds
Where the control is on screen, in the view's space - the same rectangle hit-testing uses for the control itself, without any overlay a control adds to Bounds (an open dropdown, say).
public Rectangle GlobalBounds { get; }
Property Value
Remarks
Location is already in view space: every layout arranges its children from its own location, not from zero. This used to add each parent's location on top, which counted every container's offset twice and put anything nested somewhere it was not.
HasDeclaredHeight
True when the view declared a height.
public bool HasDeclaredHeight { get; }
Property Value
HasDeclaredWidth
True when the view declared a width.
public bool HasDeclaredWidth { get; }
Property Value
HasFillOrBorder
Whether any of the fill, border or shadow is set, so that something is drawn for the control.
public bool HasFillOrBorder { get; }
Property Value
HoverKey
A name for what the pointer is resting on when it is over this element, which the game asks the view for with HoverKeyAt(Vector2): an item's place, say, to describe it.
public string HoverKey { get; set; }
Property Value
IsEffectivelyDisabled
Whether this control is switched off, or sits inside something that is.
public bool IsEffectivelyDisabled { get; }
Property Value
Remarks
The same inheritance, for the same reason: disabling a group is the natural way to say "none of this is available right now", and a flat ring would otherwise let every control inside it carry on taking input.
IsEffectivelyVisible
Whether this control is on screen and every container above it is too.
public bool IsEffectivelyVisible { get; }
Property Value
Remarks
Drawing gets this for free, because a hidden layout returns before drawing its children and they are never asked. Hit-testing does not: it walks a flat ring of controls, where a button inside a hidden group still reports IsVisible true, because nothing ever told it otherwise. That is the whole of the tabbed-screen bug -- the hidden tab's buttons kept taking clicks at the bounds they were last arranged at.
IsPanelTitle
Pressing this, away from a control, and dragging moves the panel it is in.
public bool IsPanelTitle { get; set; }
Property Value
IsVisible
Whether the control is shown. Setting it invalidates the layout that holds the control.
public bool IsVisible { get; set; }
Property Value
Location
The top-left corner of the control, in the view's space. Set by the layout that arranges it.
public Vector2 Location { get; }
Property Value
Logger
The logger the control writes to.
protected ILogger Logger { get; }
Property Value
Margin
The space the parent layout reserves around this control. None by default.
public Spacing Margin { get; set; }
Property Value
Owner
The view this control belongs to.
public View Owner { get; protected set; }
Property Value
Parent
The layout that holds this control, or null when it is not in one.
public UIElement Parent { get; }
Property Value
Shadow
A soft drop shadow drawn behind the fill, or null for none.
public BoxShadow Shadow { get; set; }
Property Value
ShowDebugBounds
Whether every control draws an outline of its Bounds. Off by default; the UI render host turns it on to check layout.
public static bool ShowDebugBounds { get; set; }
Property Value
Size
The size of the control in pixels. Set by the layout that arranges it, and by controls that size themselves from their content.
public Vector2 Size { get; }
Property Value
Methods
Dispose()
Releases what the control holds. A control that holds resources overrides this and calls the base.
public virtual void Dispose()
DrawBounds()
Draws an outline of Bounds when ShowDebugBounds is on. Does nothing otherwise.
protected void DrawBounds()
DrawFillAndBorder()
Draws FillColor and BorderColor over this control's current Bounds. Call it before drawing content so the fill lands behind.
protected void DrawFillAndBorder()
Remarks
Shapes and sprites share one command buffer that preserves submission order across both kinds (see RenderEncoderCommandBuffer.Flush), so this composes correctly with sprite draws without touching ZIndex - which would flip the whole view into sorting mode and scramble painter's order everywhere else.
DrawFillAndBorder(Rectangle)
As DrawFillAndBorder(), but over an explicit rect rather than the whole control - for a control whose chrome covers only part of its bounds, such as a checkbox whose box sits beside its label.
protected void DrawFillAndBorder(Rectangle bounds)
Parameters
boundsRectangle
Initialize()
Does nothing. The framework does not call it on controls, so a subclass that needs setup overrides it.
public virtual void Initialize()
InvalidateLayout()
Tells the containers above this control that they need to arrange again.
public void InvalidateLayout()
Remarks
The whole chain, not just the immediate parent. A layout that sizes itself to its contents changes size when a descendant does, which changes where its parent has to put it -- so stopping at one level leaves every container above that one arranged for the size things used to be.
Found in Odyssey: a repeater sitting in an auto-height panel, itself centred in the window, grew from nothing to one row when the player created their first character. The panel re-arranged; the centring stack above it did not, so the panel kept the position and extent it had when the list was empty and the new row drew over the message of the day below it. Rebuilding the screen fixed it, because a fresh layout pass computed everything at once -- which is the signature of a missed invalidation rather than a wrong measurement.
Px(float)
One of a control's own built-in pixel measurements - an inset, a gap, a default font size - at the scale its view was built at. Everything a view declares is scaled as it is built; this is for the numbers written into the control itself, which would otherwise stay the same size while everything around them grew or shrank.
protected float Px(float pixels)
Parameters
pixelsfloat
Returns
RequireEncoderScope()
The render encoder of the view that owns this control.
protected IRenderEncoderScope RequireEncoderScope()
Returns
Exceptions
- InvalidOperationException
The control is drawn outside its view's render scope.
Set<T>(ref T, T, string)
Stores value in field when it differs from the current
value. Returns true when it changed.
protected bool Set<T>(ref T field, T value, string propertyName = null)
Parameters
fieldTvalueTpropertyNamestring
Returns
Type Parameters
T