Skip to content

Drawables

Building Controls

Custom controls are built by composing drawables into reusable components using M2Panel as a base class. Once created, a custom control behaves like any other drawable - it can be added to screens, panels, or nested inside other custom controls. This enables a high-level, modular UI architecture where complex interfaces are assembled from self-contained, reusable building blocks.

Drawable Building Blocks

HUD Drawables

Drawable Description
M2Text Single-line text with font, scale, alignment, and trim
M2RectFilled Filled rectangle (solid color or gradient)
M2RectOutline Rectangle outline with stroke
M2EllipseFilled / M2EllipseOutline Circle and ellipse variants
M2EllipseFrame Round mask frame - its inner ellipse is transparent to touch
M2Arc Arc or ring segment with start/end angles
M2Line Single line segment
M2Path Multi-point polyline
M2Triangles / M2Strip / M2Fan 2D geometry primitives
M2Image Displays an uploaded M2ImageResource, with an optional loading placeholder
M2SpriteImage Displays one frame (a sub-region) of a sprite sheet
M2Texture Displays an M2TextureResource - an off-screen render target
M2VideoClip Plays a short H.264 clip

Containers

Drawable Description
M2Panel Positions and groups child drawables, with optional clipping - see below
M2ArPanel A 2D panel placed in AR world space, always facing the user

AR Drawables

Drawable Description
M2ArMesh Textured or solid-color 3D triangle mesh
M2ArLines 3D line segments
M2ArPoints 3D point cloud
M2ArLight Light source for shading AR meshes

See the LOS Kit for placing content in AR.

Multi-Line Text Controls

The SDK includes ready-made controls for text that spans several lines:

Control Description
M2TextPanel Wrapping multi-line text with scrolling and an optional scrollbar
M2TextTicker Multi-line text revealed a line or a word at a time
M2TextMarquee Single-line text that scrolls sideways when it does not fit

Container Patterns

M2Panel

M2Panel is a container for grouping child drawables. Use it to create bounded UI regions. Both M2Panel and M2ArPanel support hardware clipping via clip(true), which clips child content to the panel's bounds.

val panel = M2Panel("status-bar")
panel.setXY(0f, 0f)
panel.setWidthHeight(640f, 50f)

val label = M2Text("status-label")
label.setFont(M2FontResource.fontSmall)
    .setText("Status: Connected")
    .setXY(10f, 25f)

panel.add(label)
screen.add(panel)

Composing a Control

Custom controls should build their child drawables in onCreate(), which is called when the control's owning screen becomes active. This ensures the drawable tree is constructed in the correct lifecycle stage.

class StatusBadge(private val text: String, private val color: M2Color) : M2Panel("badge") {
    private val bg = M2RectFilled("badge-bg")
    private val label = M2Text("badge-label")

    init {
        setWidthHeight(120f, 36f)
    }

    override fun onCreate() {
        super.onCreate()

        bg.setWidthHeight(120f, 36f)
        bg.setColor(color)
        add(bg)

        label.setFont(M2FontResource.fontSmall)
            .setText(text)
            .setAlign(M2Align.CenterBoth)
            .setColor(M2Color.White)
        label.setXY(60f, 18f)
        add(label)
    }

    fun updateText(newText: String) {
        label.setText(newText)
    }
}

See Also