Class DecoratorView<T>
Definition
Namespace: StardewUI.Widgets
Assembly: StardewUI.dll
A view that owns and delegates to an inner view.
public class DecoratorView<T> : StardewUI.IView, System.IDisposable,
System.ComponentModel.INotifyPropertyChanged
Type Parameters
T
The specific type of view that the decorator owns.
Inheritance
Object ⇦ DecoratorView<T>
Implements
IView, IDisposable, INotifyPropertyChanged
Remarks
Decorator views, while not abstract, are used as a base type for other composite views, and primarily intended for framework use. Custom widgets should normally use ComponentView<T> instead, which incorporates lazy loading and other conveniences for minimalistic implementations.
The inner view is considered to be owned by the decorator; it will be assigned any values that were assigned to the decorator itself, such as Layout, and if it implements IDisposable, then it will be disposed along with the decorator.
Members
Constructors
Name | Description |
---|---|
DecoratorView<T>() | Initializes a new DecoratorView<T> instance. |
Properties
Name | Description |
---|---|
ActualBounds | The bounds of this view relative to the origin (0, 0). |
ClipOrigin | Origin position for the ClipSize. |
ClipSize | Size of the clipping rectangle, outside which content will not be displayed. |
ContentBounds | The true bounds of this view's content; i.e. ActualBounds excluding margins. |
FloatingBounds | Contains the bounds of all floating elements in this view tree, including the current view and all descendants. |
IsFocusable | Whether or not the view can receive controller focus, i.e. the stick/d-pad controlled cursor can move to this view. Not generally applicable for mouse controls. |
Layout | The current layout parameters, which determine how Measure(Vector2) will behave. |
Name | Simple name for this view, used in log/debug output; does not affect behavior. |
Opacity | Opacity (alpha level) of the view. |
OuterSize | The true computed layout size resulting from a single Measure(Vector2) pass. |
PointerEventsEnabled | Whether this view should receive pointer events like Click or Drag. |
PointerStyle | Pointer style to use when this view is hovered. |
ScrollWithChildren | If set to an axis, specifies that when any child of the view is scrolled into view (using ScrollIntoView(IEnumerable<ViewChild>, Vector2)), then this entire view should be scrolled along with it. |
Tags | The user-defined tags for this view. |
Tooltip | Tooltip data to display on hover, if any. |
Transform | Local transformation to apply to this view, including any children and floating elements. |
TransformOrigin | Relative origin position for any Transform on this view. |
View | The inner view that is decorated by this view. |
Visibility | Drawing visibility for this view. |
ZIndex | Z order for this view within its direct parent. Higher indices draw later (on top). |
Methods
Name | Description |
---|---|
ContainsPoint(Vector2) | Checks if a given point, relative to the view's origin, is within its bounds. |
Dispose() | |
Draw(ISpriteBatch) | Draws the content for this view. |
FocusSearch(Vector2, Direction) | Finds the next focusable component in a given direction that does not overlap with a current position. |
GetChildAt(Vector2, Boolean, Boolean) | Finds the child at a given position. |
GetChildPosition(IView) | Computes or retrieves the position of a given direct child. |
GetChildren(Boolean) | Gets the current children of this view. |
GetChildrenAt(Vector2) | Finds all children at a given position. |
GetDefaultFocusChild() | Gets the direct child that should contain cursor focus when a menu or overlay containing this view is first opened. |
HasOutOfBoundsContent() | Checks if the view has content or elements that are all or partially outside the ActualBounds. |
IsDirty() | Checks whether or not the view is dirty - i.e. requires a new layout with a full Measure(Vector2). |
IsVisible(Vector2?) | Checks if the view is effectively visible, i.e. if it has anything to draw. |
Measure(Vector2) | Performs layout on this view, updating its OuterSize, ActualBounds and ContentBounds, and arranging any children in their respective positions. |
OnButtonPress(ButtonEventArgs) | Called when a button press is received while this view is in the focus path. |
OnButtonRepeat(ButtonEventArgs) | Called when a button press is first received, and at recurring intervals thereafter, for as long as the button is held and this view remains in the focus path. |
OnClick(ClickEventArgs) | Called when a click is received within this view's bounds. |
OnDrag(PointerEventArgs) | Called when the view is being dragged (mouse moved while left button held). |
OnDrop(PointerEventArgs) | Called when the mouse button is released after at least one OnDrag(PointerEventArgs). |
OnLayout() | Runs whenever layout occurs as a result of the UI elements changing. |
OnPointerMove(PointerMoveEventArgs) | Called when a pointer movement related to this view occurs. |
OnPropertyChanged(PropertyChangedEventArgs) | Raises the PropertyChanged event. |
OnPropertyChanged(string) | Raises the PropertyChanged event. |
OnUpdate(TimeSpan) | Runs on every update tick. |
OnWheel(WheelEventArgs) | Called when a wheel event is received within this view's bounds. |
RegisterDecoratedProperty<TValue>(DecoratedProperty<T, TValue>) | Registers a DecoratedProperty<T, TValue>. |
ScrollIntoView(IEnumerable<ViewChild>, Vector2) | Attempts to scroll the specified target into view, including all of its ancestors, if not fully in view. |
Events
Name | Description |
---|---|
ButtonPress | Event raised when any button on any input device is pressed. |
ButtonRepeat | Event raised when a button is being held while the view is in focus, and has been held long enough since the initial ButtonPress or the previous ButtonRepeat to trigger a repeated press. |
Click | Event raised when the view receives a click initiated from any button. |
Drag | Event raised when the view is being dragged using the mouse. |
DragEnd | Event raised when mouse dragging is stopped, i.e. when the button is released. Always raised after the last Drag, and only once per drag operation. |
DragStart | Event raised when mouse dragging is first activated. Always raised before the first Drag, and only once per drag operation. |
LeftClick | Event raised when the view receives a click initiated from the left mouse button, or the controller's action button (A). |
PointerEnter | Event raised when the pointer enters the view. |
PointerLeave | Event raised when the pointer exits the view. |
PointerMove | Event raised when the pointer moves within the view. |
PropertyChanged | |
RightClick | Event raised when the view receives a click initiated from the right mouse button, or the controller's tool-use button (X). |
Wheel | Event raised when the scroll wheel moves. |
Details
Constructors
DecoratorView<T>()
Initializes a new DecoratorView<T> instance.
Properties
ActualBounds
The bounds of this view relative to the origin (0, 0).
Property Value
Remarks
Typically, a view's bounds is the rectangle from (0, 0) having size of OuterSize, but there may be a difference especially in the case of negative margins. The various sizes affect layout flow and can even be negative - for example, in a left-to-right layout, a view with left margin -100, right margin 20 and inner width 30 (no padding) has an X size of -50, indicating that it actually (correctly) causes adjacent views to be pulled left along with it. However, ActualBounds
always has a positive Size, and if an implicit content offset is being applied (e.g. because of negative margins) then it will be reflected in Position and not affect the Size; the previous example would have position X = -100 and size X = 50 (30 content + 20 right margin).
In terms of usage, OuterSize is generally used for the layout itself (Measure(Vector2) and OnMeasure(Vector2) of parent views) whereas ActualBounds is preferred for click and focus targeting.
ClipOrigin
Origin position for the ClipSize.
Property Value
Remarks
If clipping is enabled by specifying a ClipSize, and the computed size of the clipping rectangle is not exactly equal to the view's OuterSize, then this determines how it will be aligned relative to this view's boundaries.
The default origin is the view's top-left corner (0, 0). This property has no effect unless the view's ClipSize is also defined.
ClipSize
Size of the clipping rectangle, outside which content will not be displayed.
Property Value
Remarks
This is defined as a layout, but unlike the view's Layout, it is not computed against the available size provided by the parent; instead, its reference size is the view's OuterSize.
A common scenario is to set this to Fill() in order to prevent drawing outside the view's own boundaries, i.e. as an equivalent to CSS overflow: hidden
. Note however that clipping occurs during the drawing phase, so a smaller clip region does not result in a smaller layout; the view will still have the same size it would have had without any clipping, but only part of it will actually get drawn. This can also be used intentionally to create some animated visual effects such as slides and wipes.
ContentBounds
The true bounds of this view's content; i.e. ActualBounds excluding margins.
Property Value
FloatingBounds
Contains the bounds of all floating elements in this view tree, including the current view and all descendants.
Property Value
IsFocusable
Whether or not the view can receive controller focus, i.e. the stick/d-pad controlled cursor can move to this view. Not generally applicable for mouse controls.
Property Value
Remarks
In other game UI code this is more typically referred to as "snap", since there is no true input focus. However, focus is the more general term and better explains what is happening with e.g. a text box.
Layout
The current layout parameters, which determine how Measure(Vector2) will behave.
Property Value
Name
Simple name for this view, used in log/debug output; does not affect behavior.
Property Value
Opacity
Opacity (alpha level) of the view.
Property Value
Remarks
Affects this view and all descendants; used to control opacity of an entire control or layout area.
OuterSize
The true computed layout size resulting from a single Measure(Vector2) pass.
Property Value
PointerEventsEnabled
Whether this view should receive pointer events like Click or Drag.
Property Value
Remarks
By default, all views receive pointer events; this may be disabled for views that intentionally overlap other views but shouldn't block their input, such as local non-modal overlays.
PointerStyle
Pointer style to use when this view is hovered.
Property Value
Remarks
As with Tooltip, the lowest-level view takes precedence over any higher-level views.
ScrollWithChildren
If set to an axis, specifies that when any child of the view is scrolled into view (using ScrollIntoView(IEnumerable<ViewChild>, Vector2)), then this entire view should be scrolled along with it.
Property Value
Remarks
For example, if the view lays out children horizontally, and some children may occupy only a very small amount of space near the top while others are much taller vertically or positioned near the bottom, it might be desirable to configure this with Vertical, so that the entire "row" is positioned within the scrollable viewport.
In other words, "if any part of me is made visible via scrolling, then all of me should be visible".
Tags
The user-defined tags for this view.
Property Value
Tooltip
Tooltip data to display on hover, if any.
Property Value
Transform
Local transformation to apply to this view, including any children and floating elements.
Property Value
TransformOrigin
Relative origin position for any Transform on this view.
Property Value
Remarks
Expects a value that represents the fraction of the view's computed layout size. For example, (0, 0)
is the top left, (0.5, 0.5)
is the center, and 1, 1
is the bottom right. null
values are equivalent to Zero.
Origins are not inherited; each view defines its own origin for its specific transform.
View
The inner view that is decorated by this view.
Property Value
T
Visibility
Drawing visibility for this view.
Property Value
ZIndex
Z order for this view within its direct parent. Higher indices draw later (on top).
Property Value
Methods
ContainsPoint(Vector2)
Checks if a given point, relative to the view's origin, is within its bounds.
Parameters
point
Vector2
The point to test.
Returns
true
if point
is within the view bounds; otherwise false
.
Dispose()
Draw(ISpriteBatch)
Draws the content for this view.
Parameters
b
ISpriteBatch
Sprite batch to hold the drawing output.
Remarks
No positional argument is included because ISpriteBatch handles its own transformations; the top-left coordinates of this view are always (0, 0).
FocusSearch(Vector2, Direction)
Finds the next focusable component in a given direction that does not overlap with a current position.
public virtual StardewUI.Input.FocusSearchResult FocusSearch(Microsoft.Xna.Framework.Vector2 position, StardewUI.Direction direction);
Parameters
position
Vector2
The current cursor position, relative to this view. May have dimensions that are negative or outside the view bounds, indicating that the cursor is not currently within the view.
direction
Direction
The direction of cursor movement.
Returns
The next focusable view reached by moving in the specified direction
, or null
if there are no focusable descendants that are possible to reach in that direction.
Remarks
If position
is out of bounds, it does not necessarily mean that the view should return null
; the expected result depends on the direction
also. The base case is when the focus position is already in bounds, and in this case a view should return whichever view can be reached by moving from the edge of that view along a straight line in the specified direction
. However, focus search is recursive and the result should reflect the "best" candidate for focus if the cursor were to move into this view's bounds. For example, in a 1D horizontal layout the rules might be:
- If the
direction
is East, and the position's X value is negative, then the result should the leftmost focusable child, regardless of Y value. - If the direction is South, and the X position is within the view's horizontal bounds, and the Y value is negative or greater than the view's height, then result should be whichever child intersects with that X position.
- If the direction is West and the X position is negative, or the direction is East and the X position is greater than the view's width, then the result should be
null
as there is literally nothing the view knows about in that direction.
There are no strict rules for how a view performs focus search, but in general it is assumed that a view implementation understands its own layout and can accommodate accordingly; for example, a grid would follow essentially the same rules as our "list" example above, with additional considerations for navigating rows. "Ragged" 2D layouts might have complex rules requiring explicit neighbors, and therefore are typically easier to implement as nested lanes.
GetChildAt(Vector2, bool, bool)
Finds the child at a given position.
public virtual StardewUI.ViewChild GetChildAt(Microsoft.Xna.Framework.Vector2 position, bool preferFocusable, bool requirePointerEvents);
Parameters
position
Vector2
The search position, relative to the view's top-left coordinate.
preferFocusable
Boolean
true
to prioritize a focusable child over a non-focusable child with a higher z-index in case of overlap; false
to always use the topmost child.
requirePointerEvents
Boolean
Whether to exclude views whose PointerEventsEnabled is currently false
.
Returns
The view at position
, or null
if there is no match.
Remarks
If multiple children overlap the same position, then this returns the topmost child, i.e. with the highest ZIndex.
GetChildPosition(IView)
Computes or retrieves the position of a given direct child.
Parameters
childView
IView
The child of this view.
Returns
The local coordinates of the childView
, or null
if the childView
is not a current or direct child.
Remarks
Implementation of this may be O(N) and therefore it should not be called every frame; it is intended for use in directional movement and other user-initiated events.
GetChildren(bool)
Gets the current children of this view.
public virtual System.Collections.Generic.IEnumerable<StardewUI.ViewChild> GetChildren(bool includeFloatingElements);
Parameters
includeFloatingElements
Boolean
Whether to include views that are not direct children, but instead members of the floating elements collection of an IFloatContainer implementation.
Returns
GetChildrenAt(Vector2)
Finds all children at a given position.
public virtual System.Collections.Generic.IEnumerable<StardewUI.ViewChild> GetChildrenAt(Microsoft.Xna.Framework.Vector2 position);
Parameters
position
Vector2
The search position, relative to the view's top-left coordinate.
Returns
A sequence of views at the specified position
, in front-to-back (reverse ZIndex) order.
GetDefaultFocusChild()
Gets the direct child that should contain cursor focus when a menu or overlay containing this view is first opened.
Returns
The child view and position where initial focus should be, either directly or indirectly as a result of a descendant receiving focus. If this IView is itself IsFocusable, then the result may be a ViewChild referencing this view.
HasOutOfBoundsContent()
Checks if the view has content or elements that are all or partially outside the ActualBounds.
Returns
Remarks
This may be the case for e.g. floating elements, and covers not only the view's immediate content/children but also that of any descendants.
IsDirty()
Checks whether or not the view is dirty - i.e. requires a new layout with a full Measure(Vector2).
Returns
true
if the view must be measured again; otherwise false
.
Remarks
Typically, a view will be considered dirty if and only if one of the following are true:
- The Layout has changed
- The content has changed in a way that could affect layout, e.g. the text has changed in a Content configuration
- The
availableSize
is not the same as the previously-seen value (see remarks in Measure(Vector2))
A correct implementation is important for performance, as full layout can be very expensive to run on every frame.
IsVisible(Vector2?)
Checks if the view is effectively visible, i.e. if it has anything to draw.
Parameters
position
Nullable<Vector2>
Optional position at which to test for visibility. If not specified, the result indicates whether any part of the view is visible.
Returns
Remarks
While Visibility acts as a master on/off switch, there may be many other reasons for a view not to have any visible content, such as views with zero Opacity, layout views with no visible children, or labels or images with no current text or sprite.
Measure(Vector2)
Performs layout on this view, updating its OuterSize, ActualBounds and ContentBounds, and arranging any children in their respective positions.
Parameters
availableSize
Vector2
The width/height that is still available in the container/parent.
Returns
Whether or not any layout was performed as a result of this pass. Callers may use this to propagate layout back up the tree, or perform expensive follow-up actions.
Remarks
Most views should save the value of availableSize
for use in IsDirty() checks.
OnButtonPress(ButtonEventArgs)
Called when a button press is received while this view is in the focus path.
Parameters
e
ButtonEventArgs
The event data.
OnButtonRepeat(ButtonEventArgs)
Called when a button press is first received, and at recurring intervals thereafter, for as long as the button is held and this view remains in the focus path.
Parameters
e
ButtonEventArgs
The event data.
OnClick(ClickEventArgs)
Called when a click is received within this view's bounds.
Parameters
e
ClickEventArgs
The event data.
OnDrag(PointerEventArgs)
Called when the view is being dragged (mouse moved while left button held).
Parameters
e
PointerEventArgs
The event data.
OnDrop(PointerEventArgs)
Called when the mouse button is released after at least one OnDrag(PointerEventArgs).
Parameters
e
PointerEventArgs
The event data.
OnLayout()
Runs whenever layout occurs as a result of the UI elements changing.
OnPointerMove(PointerMoveEventArgs)
Called when a pointer movement related to this view occurs.
Parameters
e
PointerMoveEventArgs
The event data.
Remarks
This can either be the pointer entering the view, leaving the view, or moving within the view. The method is used to trigger events such as PointerEnter and PointerLeave.
OnPropertyChanged(PropertyChangedEventArgs)
Raises the PropertyChanged event.
Parameters
args
PropertyChangedEventArgs
The event arguments.
OnPropertyChanged(string)
Raises the PropertyChanged event.
Parameters
propertyName
string
The name of the property that was changed.
OnUpdate(TimeSpan)
Runs on every update tick.
Parameters
elapsed
TimeSpan
Time elapsed since last game tick.
Remarks
Provided as an escape hatch for very unusual scenarios like responding to flips in the game's gamepadControls state.
Override this at your own extreme peril. Frequently performing any layout-affecting logic in this function can negate the performance benefits of a retained-mode UI and cause the UI to become sluggish or even completely unresponsive. Do not use it for animation; use Animator instead.
OnWheel(WheelEventArgs)
Called when a wheel event is received within this view's bounds.
Parameters
e
WheelEventArgs
The event data.
RegisterDecoratedProperty<TValue>(DecoratedProperty<T, TValue>)
Registers a DecoratedProperty<T, TValue>.
protected void RegisterDecoratedProperty<TValue>(StardewUI.Widgets.DecoratorView<T>.DecoratedProperty<T, TValue> property);
Parameters
property
DecoratedProperty<T, TValue>
The property to register.
Remarks
All DecoratedProperty<T, TValue> fields must be registered in the constructor or before they are read from or written to.
ScrollIntoView(IEnumerable<ViewChild>, Vector2)
Attempts to scroll the specified target into view, including all of its ancestors, if not fully in view.
public virtual bool ScrollIntoView(System.Collections.Generic.IEnumerable<StardewUI.ViewChild> path, out Microsoft.Xna.Framework.Vector2 distance);
Parameters
path
IEnumerable<ViewChild>
The path to the view that should be visible, starting from (and not including) this view; each element has the local position within its own parent, so the algorithm can run recursively. This is a slice of the same path returned in a FocusSearchResult.
distance
Vector2
The total distance that was scrolled, including distance scrolled by descendants.
Returns
Whether or not the scroll was successful; false
prevents the request from bubbling.
Events
ButtonPress
Event raised when any button on any input device is pressed.
Event Type
Remarks
Only the views in the current focus path should receive these events.
ButtonRepeat
Event raised when a button is being held while the view is in focus, and has been held long enough since the initial ButtonPress or the previous ButtonRepeat
to trigger a repeated press.
Event Type
Remarks
Because the game has its own logic to repeat key presses, which would cause ButtonPress to fire repeatedly, this event generally applies only to the controller; that is, it exists to allow callers to decide whether they want the handler to repeat while the button is held or to only fire when first pressed, providing slightly more control than keyboard events whose repetition is up to the whims of the vanilla game.
Only the views in the current focus path should receive these events.
Click
Event raised when the view receives a click initiated from any button.
Event Type
Drag
Event raised when the view is being dragged using the mouse.
Event Type
EventHandler<PointerEventArgs>
DragEnd
Event raised when mouse dragging is stopped, i.e. when the button is released. Always raised after the last Drag, and only once per drag operation.
Event Type
EventHandler<PointerEventArgs>
DragStart
Event raised when mouse dragging is first activated. Always raised before the first Drag, and only once per drag operation.
Event Type
EventHandler<PointerEventArgs>
LeftClick
Event raised when the view receives a click initiated from the left mouse button, or the controller's action button (A).
Event Type
Remarks
Using this event is a shortcut for handling Click and checking for IsPrimaryButton().
PointerEnter
Event raised when the pointer enters the view.
Event Type
EventHandler<PointerEventArgs>
PointerLeave
Event raised when the pointer exits the view.
Event Type
EventHandler<PointerEventArgs>
PointerMove
Event raised when the pointer moves within the view.
Event Type
EventHandler<PointerMoveEventArgs>
PropertyChanged
Event Type
RightClick
Event raised when the view receives a click initiated from the right mouse button, or the controller's tool-use button (X).
Event Type
Remarks
Using this event is a shortcut for handling Click and checking for IsSecondaryButton().
Wheel
Event raised when the scroll wheel moves.