Class ColorPickerButton

java.lang.Object
limn.scene.Widget
limn.components.ColorPickerButton

public class ColorPickerButton extends Widget
A colour, shown as a chip, that opens a ColorPicker in a dialog when clicked: the control an application reaches for when it needs a colour from the user but cannot give up a panel to a whole picker.

 ColorPickerButton accent = new ColorPickerButton(Color.rgb(0xF59E0B));
 accent.onChange(colour -> { shape.setFill(colour); shape.invalidate(); });
 

Cancel is a change, not a silence. The picker updates the chip and calls onChange on every move, so an application sees the colour live; dismissing the dialog puts the previous colour back and reports that as a change too. The button's own color() is therefore always the answer, and a caller that simply applies what it is handed is correct with no bookkeeping of its own, which is the whole reason the listener fires on the way back. Keep the listener cheap: it runs on every frame of a drag.

The caption defaults to the colour's hex and follows it. setText(java.lang.String) replaces it with anything else, including nothing: a button with an empty caption is chrome and a chip, which is the form a dense inspector column wants.

Not a Button subclass: what it draws is a value, not a label, and the two disagree about almost every line of paint. It behaves like one (hover, focus ring, Enter and Space) because a control that opens a dialog should.

Reading right to left, the chip and its caption swap sides together: the chip is the leading item of the pair and the caption follows it inwards. Nothing else moves. The box is the same size in both directions, the chip is the same square, and the colour inside it has no reading axis of its own.

  • Constructor Details

    • ColorPickerButton

      public ColorPickerButton()
      A button on opaque white.
    • ColorPickerButton

      public ColorPickerButton(Color initial)
      A button on initial.
  • Method Details

    • color

      public Color color()
      The colour on the chip. Opaque unless setAlphaEnabled(boolean) says otherwise.
    • setColor

      public ColorPickerButton setColor(Color value)
      Sets the colour without notifying, the setter an application calls when it is the source of the change, so a listener that writes back does not loop. The picker uses the notifying path instead.
    • setAlphaEnabled

      public ColorPickerButton setAlphaEnabled(boolean enabled)
      Whether the picker offers alpha at all (default true). Turning it off makes color() opaque immediately, and drops the alpha line from the dialog, for the many things being coloured that cannot be translucent.
    • isAlphaEnabled

      public boolean isAlphaEnabled()
      Whether the alpha line is offered; when off, color() is always opaque.
    • onChange

      public ColorPickerButton onChange(Consumer<Color> listener)
      Called whenever the colour changes: on every move of the picker, and once more with the previous colour if the dialog is dismissed. Never called by setColor(limn.graphics.Color).
    • text

      public String text()
      The caption as it currently reads: the colour's hex unless one was set.
    • setText

      public ColorPickerButton setText(String value)
      Replaces the caption with a fixed string; "" leaves chrome and the chip.
    • setText

      public ColorPickerButton setText(I18nString value)
      Replaces the caption with a value that follows the UI language.
    • setTextFromColor

      public ColorPickerButton setTextFromColor()
      Puts the caption back to the colour's hex, which is where it starts.
    • setDialogTitle

      public ColorPickerButton setDialogTitle(I18nString value)
      The dialog's title; "Colour" in the UI language unless set.
    • withControlSize

      public ColorPickerButton withControlSize(ControlSize size)
      Chaining form of Widget.setControlSize(limn.scene.ControlSize); setControlSize is void.
    • isPickerOpen

      public boolean isPickerOpen()
      Whether the picker dialog is up; a second click while it is does nothing.
    • openPicker

      public void openPicker()
      Raises the picker, as a click would. Public so a menu item or a keyboard shortcut elsewhere can open the same dialog this button opens.
      Throws:
      IllegalStateException - if this button is not in a scene
    • setPickerDisplayMode

      public ColorPickerButton setPickerDisplayMode(DisplayMode mode)
      Asks for the picker to be raised in a window of its own or as an overlay inside this button's window; see DisplayMode. Default DisplayMode.NATIVE_WINDOW.

      The reason to choose IN_SCENE here is usually not the platform. A colour picker is the one dialog whose whole job is to change what is behind it, so an application that shows the result live (a theme editor, a drawing tool) wants the picker and the thing it is recolouring in one window and one screenshot. A native window is also invisible to anything that captures the owner window, which is why the toolkit's own gallery raises this one in scene.

      Takes effect on the next openPicker(); a picker already up is not moved.

      See Also:
    • pickerDisplayMode

      public DisplayMode pickerDisplayMode()
      Returns:
      the presentation the next picker will be asked for.
    • 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
    • baselineOffset

      protected float baselineOffset()
      The baseline BASELINE rows align on, the expression onPaint(limn.graphics.Canvas) draws with.
      Overrides:
      baselineOffset in class Widget
    • paintOutset

      protected float paintOutset()
      The focus ring is drawn outside the box; damage has to know. See Button.
      Overrides:
      paintOutset in class Widget
    • onPaint

      protected void onPaint(Canvas canvas)
      Description copied from class: Widget
      Widget's own background/content, in local coordinates.
      Overrides:
      onPaint in class Widget
    • onMouseEvent

      protected void onMouseEvent(MouseEvent event)
      Description copied from class: Widget
      Mouse events (bubbling); call event.consume() when handled.
      Overrides:
      onMouseEvent in class Widget
    • onKeyEvent

      protected void onKeyEvent(KeyEvent event)
      Description copied from class: Widget
      Key events (focused widget first, then ancestors).
      Overrides:
      onKeyEvent in class Widget
    • onFocusGained

      protected void onFocusGained()
      Description copied from class: Widget
      Called when this widget takes keyboard focus. Default: nothing.
      Overrides:
      onFocusGained in class Widget
    • onFocusLost

      protected void onFocusLost()
      Description copied from class: Widget
      Called when this widget loses keyboard focus. Default: nothing.
      Overrides:
      onFocusLost in class Widget