Class Theme.Builder

java.lang.Object
limn.components.Theme.Builder
Enclosing class:
Theme

public static final class Theme.Builder extends Object
Collects the colours of a palette and builds one. Not thread-safe and not meant to be: build the palette, then hand the Theme around.

Colours only. Spacing, radii and typography are not per-palette and cannot be made so from here; they come from the process-wide SizeTokens table, and Theme.tokens(limn.scene.ControlSize) explains at length why. A palette changes what the toolkit looks like, never how big it is.

The three derive methods are the same expressions the built-in palettes were built from, and each reads the tones set before it: set the accent first, then deriveAccentStates(). Call them in any order relative to each other; call them again after changing an input, or the derived tone stays where the previous input put it.

Every tone is snapped to eight bits per channel on the way in, so what get(limn.components.Theme.Token) answers is what build() produces. That is the precision a hex value, a colour field and a monitor all share, and it is what makes a palette exactly representable: a tone that could not be written down would come back different from a file it had just been saved to, and two palettes that render identically would compare unequal. A colour handed in at higher precision (anything interpolated, which is most derived tones) is rounded, by at most 1/255.

  • Method Details

    • name

      public Theme.Builder name(String value)
      The palette's identifier: Theme.name, which is also what Theme.displayName() falls back to.

      Avoid a built-in's name. Display names are looked up by this string, so a palette called "Nordic" is shown under the built-in Nordic's translation in every language that has one. Anything else stands as written, since nothing could translate it.

    • dark

      public Theme.Builder dark(boolean value)
      Whether the palette is dark. It is not decoration: it decides which tones deriveAccentStates() and deriveSemanticStates() produce, and applications group and default on it. Changing it does not re-derive anything already derived.
    • cornerScale

      public Theme.Builder cornerScale(float value)
      How round the corners are; see Theme.cornerScale. Clamped to [0, MAX_CORNER_SCALE]; 1 is the shipped ramp.
      Throws:
      IllegalArgumentException - if value is not a finite number, which is what a text field hands over when it is empty
    • cornerScale

      public float cornerScale()
      The shape, as set so far.
    • fontFamily

      public Theme.Builder fontFamily(String value)
      The typeface family this palette asks for; see Theme.fontFamily. null or blank means no preference and stores Font.DEFAULT_FAMILY, which is what the built-ins carry.

      The name is not validated against the installed faces, and deliberately: a palette is a value that outlives the machine it was authored on, so a family this machine happens not to have is a legitimate thing to write down. It falls back to the embedded face when it is applied (see Theme.applyFontFamily()) rather than being rejected here, which would make a palette unloadable on the wrong laptop.

    • fontFamily

      public String fontFamily()
      The typeface family, as set so far.
    • background

      public Theme.Builder background(Color value)
      See Also:
    • surface

      public Theme.Builder surface(Color value)
      See Also:
    • surfaceRaised

      public Theme.Builder surfaceRaised(Color value)
      See Also:
    • primary

      public Theme.Builder primary(Color value)
      The accent at rest; deriveAccentStates() turns it into the ramp.
    • primaryHover

      public Theme.Builder primaryHover(Color value)
      See Also:
    • primaryPressed

      public Theme.Builder primaryPressed(Color value)
      See Also:
    • onPrimary

      public Theme.Builder onPrimary(Color value)
      See Also:
    • text

      public Theme.Builder text(Color value)
      See Also:
    • textMuted

      public Theme.Builder textMuted(Color value)
      See Also:
    • outline

      public Theme.Builder outline(Color value)
      See Also:
    • focusRing

      public Theme.Builder focusRing(Color value)
      See Also:
    • disabledFill

      public Theme.Builder disabledFill(Color value)
      See Also:
    • disabledText

      public Theme.Builder disabledText(Color value)
      See Also:
    • scrim

      public Theme.Builder scrim(Color value)
      The modal veil; see Theme.scrim. The only tone whose alpha is read rather than assumed opaque, and passing an opaque colour here is the way to make a modal hide what it blocks instead of dimming it.
    • danger

      public Theme.Builder danger(Color value)
      See Also:
    • success

      public Theme.Builder success(Color value)
      See Also:
    • warning

      public Theme.Builder warning(Color value)
      See Also:
    • info

      public Theme.Builder info(Color value)
      See Also:
    • get

      public Color get(Theme.Token token)
      This tone, as the builder currently holds it: the read half of set(limn.components.Theme.Token, limn.graphics.Color).
    • set

      public Theme.Builder set(Theme.Token token, Color value)
      Sets any tone by token, the form a generic editor or parser uses.
    • name

      public String name()
      The palette's name, as set so far.
    • isDark

      public boolean isDark()
      Whether the palette is dark, as set so far.
    • deriveAccentStates

      public Theme.Builder deriveAccentStates()
      Hover and pressed, from the accent: lightened toward white by 16% dark / 12% light, and darkened toward black by 20%.

      The darkening is the one to check by eye rather than trust. A light accent carrying dark label ink has almost no room to darken: 20% can drop the label below 4.5:1, so pressing the button makes its own text harder to read. That is why the toolkit's own palette spells its ramp out instead of calling this.

    • deriveDisabled

      public Theme.Builder deriveDisabled()
      The disabled pair, by fading the raised surface and the body ink halfway back into the canvas, a control that reads as absent rather than as a second colour. Reads surfaceRaised, text and background.
    • deriveSemanticStates

      public Theme.Builder deriveSemanticStates()
      The semantic four, from the generic tones that read on any surface of this mode. Reads only dark.

      They are deliberately not derived from the accent: red means error in every palette, and a palette whose danger colour follows its brand is a palette where an error looks like a link. Override individually where a tone has to clear 4.5:1 on a surface these generic ones do not.

    • build

      public Theme build()
      The palette. Every field is non-null by construction (the builder is seeded from a built-in and every setter null-checks), so this cannot fail. The builder stays usable afterwards and builds a fresh palette each call.