Gamepad — Layouts & Customizing
Custom layouts
Section titled “Custom layouts”A layout is a GamepadLayout holding a list of GamepadElements. Every GamepadLayouts.* call returns a
fresh copy that is safe to change, so the quickest custom layout is a tweaked preset:
var layout = GamepadLayouts.Standard();layout.Find("ls")!.IsFloating = true; // left stick follows the thumblayout.Find("a")!.IsTurbo = true; // rapid-fire Alayout.Find("a")!.Label = "Jump";
Pad.ControllerLayout = layout;Or build one from scratch:
var layout = new GamepadLayout{ Name = "Racer", FaceStyle = GamepadFaceStyle.Xbox, Elements = [ new() { Id = "steer", Kind = GamepadElementKind.Stick, Button = GamepadButton.LeftStick, Anchor = GamepadAnchor.BottomLeft, X = 110, Y = -110, Width = 150, Height = 150 }, new() { Id = "gas", Kind = GamepadElementKind.Trigger, Button = GamepadButton.RightTrigger, Shape = GamepadElementShape.Rounded, Anchor = GamepadAnchor.BottomRight, X = -80, Y = -120, Width = 90, Height = 140, Label = "GAS" }, new() { Id = "brake", Kind = GamepadElementKind.Trigger, Button = GamepadButton.LeftTrigger, Shape = GamepadElementShape.Rounded, Anchor = GamepadAnchor.BottomRight, X = -190, Y = -100, Width = 90, Height = 100, Label = "BRAKE", Color = "#B91C1C" } ]};GamepadElement |
Meaning |
|---|---|
Id |
Unique within the layout. Find(id) looks it up. |
Kind |
Button, Trigger (also drives its trigger axis), DPad or Stick |
Button |
What a button reports. For a stick, LeftStick or RightStick says which stick it is. |
Shape |
Circle, Pill or Rounded — buttons and triggers only |
Anchor, X, Y |
The element’s centre, offset from one of nine anchor points in device-independent units (positive Y is down) |
Width, Height |
Size in device-independent units |
Label, Color |
Override the face style’s label and fill (#RRGGBB) |
IsFloating, FloatingZone |
Floating stick and how far around it a touch grabs it |
IsTurbo |
Rapid-fire while held |
DesignWidth / DesignHeight are the canvas the layout was designed on. Only Uniform sizing uses
them. BodyRoundness shapes the body drawn behind it — 0.5 is the SNES “dog bone”.
Letting the player rearrange it
Section titled “Letting the player rearrange it”Set IsEditing and the controller stops playing. The player drags an element to move it and pinches
with a second finger to resize it. When a move finishes, LayoutEdited fires and ControllerLayout
holds the edited layout. The MAUI property is two-way by default, and Blazor supports
@bind-ControllerLayout.
Persist it as JSON:
Pad.LayoutEdited += (_, layout) => Preferences.Set("pad", layout.ToJson());
var saved = Preferences.Get("pad", null);if (saved != null) Pad.ControllerLayout = GamepadLayout.FromJson(saved);<GamepadView @bind-ControllerLayout="layout" IsEditing="editing" OnLayoutEdited="l => store.SaveAsync(l.ToJson())" />The JSON writes enums as names, so a saved layout survives a library update that reorders them. Reset
by setting ControllerLayout back to null, which returns to Preset.
Colours
Section titled “Colours”MAUI (Color) |
Blazor (CSS string) | CSS variable | Paints |
|---|---|---|---|
ButtonColor |
ButtonColor |
--shiny-gamepad-button |
Unpressed elements |
PressedColor |
PressedColor |
--shiny-gamepad-pressed |
Pressed d-pad arms, stick knobs |
LabelColor |
LabelColor |
--shiny-gamepad-label |
Labels and glyphs the face style leaves uncoloured |
OutlineColor |
OutlineColor |
--shiny-gamepad-outline |
Element outlines |
BodyColor |
BodyColor |
--shiny-gamepad-body |
The controller body in Uniform sizing |
AccentColor |
AccentColor |
--shiny-gamepad-accent |
Edit-mode outlines, a clicked stick’s ring |
On Blazor you can also set the CSS variables from a stylesheet. Parameters that are left null fall
back to them.
Other properties
Section titled “Other properties”| Property | Default | |
|---|---|---|
ControllerScale |
1 |
Size multiplier in Anchored sizing |
DPadMode |
EightWay |
FourWay never reports a diagonal |
TurboRate |
10 |
Presses per second for turbo buttons |
StickClickEnabled |
true |
Double-tap-and-hold clicks a stick |
PassThrough |
true |
Touches that miss every element reach the view beneath |
ShowBody |
null |
Draw the body — null draws it only in Uniform sizing |
PlayerIndex |
null |
The player slot Gamepad reports |
GamepadId |
generated | Stable IGamepad.Id, kept across the pads a view hands out |
GamepadName |
“On-Screen Gamepad” | IGamepad.Name |


