How-To: Shape a Bar
Goal: a four-slot diamond bar (the soulslike cross) with a bigger center slot presented by its own widget - authored entirely in the layout asset, laid out identically by the layout editor's canvas and the in-game HUD.
Style.SlotSize set to a real size (for example 56 x 56): a Freeform slot is placed by its top-left corner and its size, so a widget-designed (zero) size cannot be laid out and IsDataValid warns.1. Switch the bar to Freeform
Open the layout asset, click the bar's header on the canvas and set Style.Arrangement to Freeform. Nothing moves yet: slots without an authored placement continue the row they were in (ResolveSlotPlacement's fallback), so a bar looks the same the moment you flip it. The canvas now draws that bar on a gridded panel instead of a wrap box, and a row of Arrange buttons appears under it.
2. Arrange, then drag
Press Arrange: Ring - with five slots that is a pentagon, with four it is the diamond. Then drag any tile to where you want it; drops snap to 8 px (hold Shift for free placement) and every move is one undoable transaction that writes Position into the bar's Style.SlotPlacements. Ctrl+drop a tile onto another swaps the two slots' contents (lock, default binding, filter) while the positions and keys stay put. The tooltip of a tile shows its position, size and Z order; the Details panel shows the same placement next to the slot's input action for typed-in precision.
3. Make one slot special
Select the center slot. Its Placement row in the Details panel is an override of the bar's Style: set Size to 72 x 72, ZOrder to 1 so it draws over its neighbors, and SlotWidgetClass to a slot widget with the frame you want (duplicate W_ActionBar_Slot, swap its SlotMaterial class default for MI_CrimsonActionBar_Slot_Circle or restyle its Visuals). Leave the rest blank - blank means "whatever the bar's Style says". The tile gets a W badge and takes its new size right away; the look itself is the widget's, so the canvas shows a neutral tile of the right size until phase two renders the real widget. The override works on Flow bars as well; only Position and ZOrder are Freeform-only.
4. Share the shape (optional)
Several bars that should look alike (two identical cross bars, a set of pet bars) do not need the shape authored per bar. Click Layout settings and fill SharedSlotPlacements once - or arrange one bar and copy its Style.SlotPlacements array over - then tick Style.bUseSharedPlacements on every bar that should read it. The canvas header says freeform (shared placements), drags on any of those bars edit the shared list, and the Details panel's placement row points at it.
Panel_Slots may be a Canvas Panel itself; any other panel gets one as its single child, sized to the placed slots), the center slot is bigger and presented by its own widget, and keys 1-4 still fire the slots by index - shape never changes which key is which.How it works
Placements are per bar and index-aligned with SlotInputActions, not per page: key i and position i travel together across every page, so a stance page cannot accidentally reshuffle the cross. UCrimsonActionBarLayoutDefinition::ResolveSlotPlacement is the one reader both sides use - it picks the bar's own list or the shared one, continues the row past the end of the list, and fills every blank from the bar's Style. UCrimsonCoreActionBarWidget::RebuildSlots (CrimsonCore) and SCrimsonActionBarLayoutPreview (the editor canvas) both call it and place with the same top-left anchor, which is why the preview's geometry is the game's. What a slot looks like is never in the asset: the slot widget owns its material and colors and reacts to the per-slot state and the On ... Changed events (hover, press, drag, drop feedback, cooldown, active, stale, locked, availability) - see How-To: Bind a Slot Widget.
See also
- How-To: Bind a Slot Widget
- Concept: Bars, Pages and the Store
- API Reference -> Layout definition