ADR-125: User interface components for SDK 7

More details about this document
Latest published version:
https://adr.decentraland.org/adr/ADR-125
Authors:
menduz
Feedback:
GitHub decentraland/adr (pull requests, new issue, open issues)
Edit this documentation:
GitHub View commits View commits on githistory.xyz

Abstract

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.

Specification

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 ?
}

UiDropdown

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
}

RFC 2119 and RFC 8174

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.

License

Copyright and related rights waived via CC0-1.0. Living