This specification covers an initial set of components of the SDK to create flexbox-based user interfaces. The components only describe behavior and configuration skipping position and sizing, that is considered layouting and is given by the UiTransform component from ADR-124.
PointerEvents
component
We are going to reuse the existing PointerHoverFeedback component, the name will be changed to PointerEvents to reflect its ultimate purpose.
The PointerEvents
component is used to signal the renderer about which entities
are eligible for pointer interactions, it is RECOMMENDED to use this component as filter for
raycasts.
enum PointerEventType {
PET_UP = 0;
PET_DOWN = 1;
PET_HOVER_ENTER = 2;
PET_HOVER_LEAVE = 3;
}
// We can talk about this name
message PBPointerEvents {
message Info {
optional common.InputAction button = 1; // default=InputAction.ANY
optional string hover_text = 2; // default='Interact'
optional float max_distance = 3; // default=10
optional bool show_feedback = 4; // default=true
}
message Entry {
PointerEventType event_type = 1;
Info event_info = 2;
}
repeated Entry pointer_events = 1;
}
PointerEventsResult
component
The same component that is currently used for 3D objects will be used to process the UI pointer events, this will leverage the existing codebase while reducing moving parts and cognitive load on the users of the SDK.
Notice that this component has many properties that are not useful for the 2D UI like "analog". The behavior for those fields in the UI is yet to be defined.
message PBPointerEventsResult {
// a list of the last N pointer commands (from the engine)
repeated PointerCommand commands = 1;
// this message represents a pointer event, used both for UP and DOWN actions
message PointerCommand {
common.InputAction button = 1; // identifier of the input
RaycastHit hit = 2;
PointerEventType state = 4;
int32 timestamp = 5; // could be a Lamport timestamp
optional float analog = 6; // if the input is analog then we store it here
}
}
UiText
component
A "rendering component", signals the engine to render a 2D text in the specified entity. The size and position of the label will be defined by the ADR-124
message PBUiText {
string value = 1;
optional decentraland.common.Color4 color = 2; // default=(1.0,1.0,1.0,1.0)
TextAlignMode text_align = 3;
Font font = 4; // default=0 - SansSerif
optional int32 font_size = 5; // default=10
}
UiBackground
component
This component sets the background of a UI element. When a texture and a color are specified, the color multiplies the texture to enable easy customization of UI elements in different states i.e. active, focused, highlighted. A 9-slices background mode can be specified, affecting the specified texture.
message PBUiBackground {
// default=(0.0, 0.0, 0.0, 0.0)
optional decentraland.common.Color4 color = 1;
// texture for the background
optional decentraland.common.TextureUnion texture = 2;
// texture mode
BackgroundTextureMode texture_mode = 3;
// texture_slices, represents the top | right | bottom | left sizes of the
// slices for the borders. Values are percentages of the texture.
// default=(1/3,1/3,1/3,1/3)
optional Rect texture_slices = 4;
// when STRETCH is selected, the uvs are configurable
// default=default plane uvs
optional repeated float uvs = 5;
}
enum BackgroundTextureMode {
// https://docs.unity3d.com/Manual/9SliceSprites.html
// https://developer.mozilla.org/en-US/docs/Web/CSS/border-image-slice
// https://forum.unity.com/threads/how-does-slicing-in-ui-tookkit-works.1235863/
NINE_SLICES = 0; (default)
// CENTER enables the texture to be rendered centered in relation to the
// element. If the element is smaller than the texture then the background
// should use the element as stencil to cut off the out-of-bounds area
CENTER = 1;
// STRETCH enables the texture to cover all the area of the container,
// adopting its aspect ratio. It takes the UVs from the uvs field
STRETCH = 2;
}
UiButton
component
UiButton can be implemented with a UiText+UiTransform+UiBackground
.
UiInput
UiInput adds an editable behavior to the UiEntity. By default it can render a placeholder
label. The size and position of the UiInput
will be defined by the
ADR-124
message UiInput {
// placeholder text
optional string placeholder = 1;
// color of the text
// default=(0.0,0.0,0.0,1.0)
optional decentraland.common.Color4 color = 2;
// color of the placeholder text
// default=(0.3,0.3,0.3,1.0)
optional decentraland.common.Color4 placeholder_color = 3;
// makes it non-interactable
bool disabled = 4;
// text align
TextAlignMode text_align = 10;
// font family default=0 - SansSerif
Font font = 11;
// font size default=10
optional int32 font_size = 12;
}
message UiInputResult {
string value = 1
// Maybe we can add some state info of the input here such as Focused/Selected etc ?
}
message UiDropdown {
// does this accept an empty selection?
// a.k.a "null" state
bool accept_empty = 1;
// placeholder for "null" state
optional string empty_label = 2;
// list of strings
repeated string options = 3;
// default=-1 when accept_empty==true
// default=0 when accept_empty==false
int32 selected_index = 4;
// makes it non-interactable
bool disabled = 4;
// text align
TextAlignMode text_align = 10;
// font family default=0 - SansSerif
Font font = 11;
// font size default=10
optional int32 font_size = 12;
}
message UiDropdownResult {
int32 value = 1
}
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.