Class ColorPicker
Hue and saturation live on the widget rather than being re-derived from the colour. Grey has no hue and black has no saturation, so a colour alone cannot say where the cursor was: dragging the value down to black and back up would otherwise return red. What was last chosen survives the trip.
Alpha is a mode. setAlphaEnabled(boolean) removes the whole alpha line, rail
and number together, and color() then always returns an opaque colour. Alpha
is the last line, so losing it shortens the picker rather than rearranging it.
Two opposite answers about direction live in this one widget, and unifying them would be wrong. The rails are value axes laid along the reading axis, so their sweep, their thumb, their pointer and their horizontal arrows all turn round together when the picker reads right to left. The saturation/value field and the hue ramp do not turn round: the first is a colour space, whose white corner is a convention every artist has met and not a side of the page, and the second is vertical, which no direction touches. The ramp still changes sides, because the row holding it is what places it.
The answer is a display-range Color. An application authoring light rather
than pixels needs a multiplier beside this widget, not inside it: the swatch cannot
show what such a multiplier does, since normalising an over-range colour for display
divides it straight back out.
Not a dialog; put it in one with Dialog.setContent(limn.scene.Widget), or inline it in a
panel. final, unlike most components here: it is a composite of four painted
parts wired to one model, and a subclass would be overriding paint and layout it does
not own. Compose one instead.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumWhich numeric model the channel row is showing. -
Constructor Summary
ConstructorsConstructorDescriptionA picker starting on opaque white, with the alpha line offered. -
Method Summary
Modifier and TypeMethodDescriptioncolor()The chosen colour.format()The notation the channel rows are currently showing.booleanWhether the alpha line is offered; when off,color()is always opaque.Fires on every move: a picker shows its answer live, it does not wait for OK.Fires once with the settled colour when a drag ends, the difference between a preview and a decision, and the same splitSlider.onChange/Slider.onCommitmakes.protected voidonKeyEvent(KeyEvent event) Key events (focused widget first, then ancestors).protected voidonLayout()Containers position children here (measure +Widget.layoutBox(float, float, float, float)per child).protected SizeonMeasure(Constraints constraints) Reports the size this widget wants withinconstraints.setAlphaEnabled(boolean enabled) Whether the picker offers alpha at all (defaulttrue).Moves the selection.setFormat(ColorPicker.Format format) Which numeric model the channel rows show.setInitialColor(Color color) Sets the colour and the "before" swatch: this is what opening the picker on an existing colour means.Methods inherited from class limn.scene.Widget
acceptsTextInput, add, baselineOffset, baselineOffsetOf, caretRect, children, clipboard, clipsChildren, controlSize, cursor, declaredControlSize, declaredLayoutDirection, declaredLocale, focusArrivedByTraversal, height, hitTest, imageCursor, invalidate, invalidate, isEnabled, isFocusable, isFocused, isShowing, isVisible, layoutBox, layoutDirection, locale, localToSceneX, localToSceneY, markNeedsContainedLayout, markNeedsLayout, measure, moveChild, neutralBase, onAttached, onCharTyped, onDetached, onFileDrop, onFocusGained, onFocusLost, onMouseEvent, onPaint, onPaintOverlay, onPreedit, overlayPassesPointer, paintChildren, paintOutset, paintWidget, parent, remove, requestFocus, revealInView, scene, sceneToLocalX, sceneToLocalY, setControlSize, setCursor, setEnabled, setFocusable, setImageCursor, setInheritanceHost, setLayoutDirection, setLocale, setTooltip, setTooltip, setVisible, shapeText, textRuler, tooltip, width, x, y
-
Constructor Details
-
ColorPicker
public ColorPicker()A picker starting on opaque white, with the alpha line offered.
-
-
Method Details
-
color
The chosen colour. Opaque unlesssetAlphaEnabled(boolean)says otherwise. -
setInitialColor
Sets the colour and the "before" swatch: this is what opening the picker on an existing colour means. UsesetColor(limn.graphics.Color)to move the selection without moving the comparison. -
setColor
Moves the selection. Hue and saturation are taken fromcoloronly when it has them: a grey has no hue to read, and overwriting the current one with zero would swing the field to red for no reason the artist can see. -
setAlphaEnabled
Whether the picker offers alpha at all (defaulttrue). Turning it off hides the ramp and the field and makescolor()opaque, 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. -
setFormat
Which numeric model the channel rows show. The visual field is always HSV.The one entry point, whichever end it came from: a tab the user clicked arrives here through
TabbedPane.onSelect(java.util.function.Consumer<java.lang.Integer>), and this pushes the selection back the other way for a caller that set it. That round trip is why the guard exists: unlike a segmented control, a tabbed pane reports a programmatic selection too, so without it one switch would runsyncFields()twice: once from the notification and once here. -
format
The notation the channel rows are currently showing. -
onChange
Fires on every move: a picker shows its answer live, it does not wait for OK. That makes a delivery a preview: seeonCommitfor the one that is a decision.- Throws:
NullPointerException- iflisteneris null, as everywhere else in this set
-
onCommit
Fires once with the settled colour when a drag ends, the difference between a preview and a decision, and the same splitSlider.onChange/Slider.onCommitmakes. This is where an undo entry is closed, or a value written to a document.- Throws:
NullPointerException- iflisteneris null
-
onMeasure
Description copied from class:WidgetReports the size this widget wants withinconstraints. 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
ControlSizeand theLayoutDirectiononce each here and thread them down; never read either in a constructor. The locale needs no threading: it is in scope, andI18n.locale()answers it wherever text is resolved. -
onLayout
protected void onLayout()Description copied from class:WidgetContainers position children here (measure +Widget.layoutBox(float, float, float, float)per child). -
onKeyEvent
Description copied from class:WidgetKey events (focused widget first, then ancestors).- Overrides:
onKeyEventin classWidget
-