Class TokenBox

java.lang.Object
limn.scene.Widget<TokenBox>
limn.components.TokenBox

public final class TokenBox extends Widget<TokenBox>
A SizedBox whose fixed dimensions come from the resolved ControlSize step instead of from a number baked at construction.

The fourth of the Token* family: TokenRow, TokenColumn and TokenPadding do this for gaps and insets, and this does it for an extent. It exists for the size-axis trap the repository keeps running into: a widget has no parent while it is being built, so a size read there resolves against the process default and stays there forever, whatever step the eventual parent declares.


 // the colour picker, as wide as the step says a picker in a dialog should be
 new TokenBox(SizeTokens::colorDialogW, null, picker)
 

null means "unset" on either axis, exactly as SizedBox.UNSET does: that axis is whatever the child measures to. It is documented against that class and extends Widget directly; it is not a SizedBox and shares no code with one.

To an assistive technology this widget is not there. It declares no role, no name, no action and no state, so the walk's transparency predicate deletes it and its child publishes in its place — and because onLayout hands that child the whole box at the origin, the rectangle the child publishes is the one this widget would have. The deletion therefore costs a reader nothing at all, which is not true of a padding or a row. Naming an instance materialises a group over that same rectangle, so a name here buys a name and no geometry.

What this class guarantees a reader is when the extent is read and not what it returns: the TokenBox.Extent runs inside the measure pass, against the step resolved with a parent in place, and is then clamped by the incoming constraints like any other request. An Extent that ignores its argument is a constant, and a tight parent discards the number either way.

Like every layout, it declares how far its child may paint past it: by default the reach of the theme's focus ring, and whatever paintOverflow(float) says instead.

  • Constructor Details

    • TokenBox

      public TokenBox(@Nullable TokenBox.Extent fixedWidth, @Nullable TokenBox.Extent fixedHeight, Widget<?> child)
      Parameters:
      fixedWidth - the width to impose, or null to take the child's
      fixedHeight - the height to impose, or null to take the child's
      child - the widget to size; never null
  • Method Details

    • paintOverflow

      public TokenBox paintOverflow(float points)
      Declares how far the child may paint past this box, in logical points, in place of the reach of the theme's focus ring, which is the default. It is what Container.paintOverflow(float) is to a container, for the one child here: the public setter of paintOutset(), and a new declaration repaints this box and its band while one already in force repaints nothing. UI thread only.
      Parameters:
      points - how far the child may paint past each side of this box, in logical points
      Returns:
      this box
      Throws:
      IllegalArgumentException - when negative, NaN or infinite
    • paintOverflowFromTheme

      public TokenBox paintOverflowFromTheme()
      Goes back to declaring the reach of the theme's focus ring for the child, which is the default; see paintOverflow(float). UI thread only.
      Returns:
      this box
    • paintOutset

      protected float paintOutset()
      What paintOverflow(float) declared, else the theme's Theme.focusRingReach(): the child is laid out over the whole box, so a ring at its edge is a ring at this box's edge. O(1) and allocation-free.
      Overrides:
      paintOutset in class Widget<TokenBox>
    • onMeasure

      protected Size onMeasure(Constraints constraints)
      Description copied from class: Widget
      Reports the size this widget wants within constraints. Called once per layout pass, and the result is cached against the constraints and the resolved axes (size step, layout direction, locale), so it must be a pure function of them and of this widget's own state.

      Resolve the ControlSize and the LayoutDirection once each here and thread them down; never read either in a constructor. The locale needs no threading: it is in scope, and I18n.locale() answers it wherever text is resolved.

      Specified by:
      onMeasure in class Widget<TokenBox>
    • onLayout

      protected void onLayout()
      Description copied from class: Widget
      Containers position children here (measure + Widget.layoutBox(float, float, float, float) per child).
      Overrides:
      onLayout in class Widget<TokenBox>