Class Expander
It opens and closes by a click on the header, by Space or Enter while the header holds the
keyboard, and from setExpanded(boolean). The content slides out over Theme.animExpand,
and appears at once when the user asked the system for less motion. Once it is closed the
content is hidden: it takes no room, no focus and no pointer, and a reader does not find it.
While it slides shut it is still drawn, as it was and not greyed, but it answers nothing from
the moment the close starts: a press on it reaches no control, Tab and an access letter pass it
by, nothing inside can take the keyboard, and a reader finds its nodes but no verb on them
acts. Closing it while the keyboard is inside moves the keyboard to the header as the close
starts, which is where the user just was. The content's own enabled state is the
application's and is never changed; opened again, it answers as before.
A reader hears the header as a button, expanded or collapsed, that controls the content;
the summary is its description. An ExpanderGroup keeps at most one of several open.
Reading right to left the arrow, the icon and the title start from the right and the summary ends on the left, and a closed arrow points to the left, where reading goes.
-
Constructor Summary
ConstructorsConstructorDescriptionA closed section with a fixed title; see theI18nStringconstructor for a localized one.Expander(I18nString title, Widget<?> content) A closed section whose title follows the UI language. -
Method Summary
Modifier and TypeMethodDescriptionTakes the summary away, assetSummary(null)would: that call does not compile, becausenullfits more than one of the overloads.protected booleanWhetherWidget.paintChildren(limn.graphics.Canvas)clips its children to this widget's bounds (scroll views, list viewports, tab strips).Widget<?> content()protected voidhandleUserChange(Change.Aspect aspect) Runs this widget's application handler for a change it has just announced.@Nullable Iconicon()booleanprotected voidonAccessibilityChild(Widget<?> child, Accessibility a) Says of the content what only this section knows: that the header names it.protected voidCalled when this widget enters a scene (attached to the tree).The application's response to the user opening or closing it: a click, Space or Enter on the header, or a reader's verb, with the new state.protected voidA group does not hold a section that is out of the scene: a form rebuilt against the same group would otherwise leave it every section of every form before, each still counted and each holding its content.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.protected voidpaintChildren(Canvas canvas) Children pass; override to clip (e.g.setContent(Widget<?> newContent) Puts other content below the header, open or closed as the section is.setExpanded(boolean value) Opens or closes it: a caller's write, so it announcesEXPANDED/CODEand runs no handler.Sets the icon at the header's start, tinted to the title's colour and drawn as authored;nulltakes it away.setIcon(@Nullable Icon newIcon, Icon.Mirroring mirroring) Sets the icon at the header's start, saying whether its drawing turns around when the interface reads right to left.setSummary(@Nullable String newSummary) Sets the summary at the header's end, in a quieter colour: what is inside, said while it is closed.setSummary(@Nullable I18nString newSummary) Sets a summary that follows the UI language, or takes it away withnull.Sets a fixed title.setTitle(I18nString newTitle) Sets a title that follows the UI language.@Nullable Stringsummary()title()Methods inherited from class limn.scene.Widget
acceptsTextInput, accessibleLabelAccessKey, accessibleLabelTarget, accessibleLabelText, add, add, announceChange, backdropReach, baselineOffset, baselineOffsetOf, caretRect, children, clipboard, clipHeight, clipWidth, clipX, clipY, controlSize, cursor, declaredControlSize, declaredLayoutDirection, declaredLocale, focusArrivedBackward, focusArrivedByTraversal, height, hitTest, hitTestChild, id, imageCursor, inheritanceHost, invalidate, invalidate, invalidateAccessible, isEnabled, isFocusable, isFocused, isRightToLeft, isSelfEnabled, isShowing, isVisible, isVisibleByItsOwnFlag, layoutBox, layoutDirection, locale, localToScene, localToSceneBounds, markNeedsContainedLayout, markNeedsLayout, markNeedsLayoutInPlace, maxHeight, maxWidth, measure, minHeight, minWidth, moveChild, moveChild, moveChild, neutralBase, notifyChange, notifyTextEdit, observeChanges, onAccessibility, onAccessibilityAction, onAccessibilityChildAction, onAccessibilityChildIdentity, onCanEdit, onCharTyped, onDragExit, onDragOver, onDragStart, onDrop, onEdit, onFocusGained, onFocusLost, onHitTest, onKeyEvent, onMouseEvent, onPaint, onPaintOverlay, onPreedit, onSyntheticAction, overlayPassesPointer, paintOutset, paintsDecoration, paintsFromBackdrop, paintWidget, parent, remove, remove, requestFocus, requestFocus, revealInView, revealInView, runHandler, scene, sceneNanos, sceneToLocal, self, setAccessibleDescribedBy, setAccessibleDescription, setAccessibleDescription, setAccessibleIgnored, setAccessibleLabelledBy, setAccessibleName, setAccessibleName, setAccessibleRole, setControlSize, setCursor, setEnabled, setFocusable, setId, setImageCursor, setInheritanceHost, setLayoutDirection, setLocale, setMaxHeight, setMaxWidth, setMinHeight, setMinWidth, setPresentedElsewhere, setTooltip, setTooltip, setVisible, shapeText, textRuler, tooltip, tooltipSource, width, x, y
-
Constructor Details
-
Expander
A closed section with a fixed title; see theI18nStringconstructor for a localized one.- Parameters:
title- the header's titlecontent- what opens below it
-
Expander
A closed section whose title follows the UI language.- Parameters:
title- the header's titlecontent- what opens below it
-
-
Method Details
-
title
- Returns:
- the title, resolved in this widget's own language
-
setTitle
Sets a fixed title. -
setTitle
Sets a title that follows the UI language. -
setIcon
Sets the icon at the header's start, tinted to the title's colour and drawn as authored;nulltakes it away. -
setIcon
Sets the icon at the header's start, saying whether its drawing turns around when the interface reads right to left.- Parameters:
mirroring-Icon.Mirroring.NEVERunless the glyph means a direction
-
icon
- Returns:
- the icon at the header's start, or null
-
setSummary
Sets the summary at the header's end, in a quieter colour: what is inside, said while it is closed. A reader hears it as the header's description.nulltakes it away. -
setSummary
Sets a summary that follows the UI language, or takes it away withnull. -
clearSummary
Takes the summary away, assetSummary(null)would: that call does not compile, becausenullfits more than one of the overloads.- Returns:
- this expander
-
summary
- Returns:
- the summary, resolved in this widget's own language, or null
-
content
- Returns:
- what opens below the header
-
setContent
Puts other content below the header, open or closed as the section is.- Parameters:
newContent- what opens below the header
-
isExpanded
public boolean isExpanded()- Returns:
- whether it is open, or opening
-
setExpanded
Opens or closes it: a caller's write, so it announcesEXPANDED/CODEand runs no handler. In a group, opening it closes the one that was open, which announces too. The same state again changes nothing and announces nothing. UI thread only. -
onChange
The application's response to the user opening or closing it: a click, Space or Enter on the header, or a reader's verb, with the new state. Never forsetExpanded(boolean), nor for a group closing it because another opened from code; to hear every change whatever caused it, watch it instead.- Parameters:
listener- the handler, ornullto clear the slot- Returns:
- this expander
- Throws:
IllegalStateException- if a handler is already registered
-
handleUserChange
Description copied from class:WidgetRuns this widget's application handler for a change it has just announced. Called byWidget.runHandler(limn.scene.Change), and so byWidget.notifyChange(limn.scene.Change), only for aUSERorigin and after every watcher has run.A component overrides it once and switches on the aspect, reading its own accessors for the payload: a slider passes
value(), a combo boxselectedIndex(), a text fieldtext(). A component with no handler does not override it.An override that does not recognise the aspect must call
super, because a subclass of a component that has a handler inherits that component's dispatch through this method: aSearchFieldthat overrode this for its own aspect and did not chain would silently deleteTextField's. The ordering lives in the base class, this is the one link in it a subclass can break, and the contract test drives every subclass through its parent's gestures to catch one that does.- Overrides:
handleUserChangein classWidget<Expander>- Parameters:
aspect- what changed; the origin isUSERor this is not called
-
onDetached
protected void onDetached()A group does not hold a section that is out of the scene: a form rebuilt against the same group would otherwise leave it every section of every form before, each still counted and each holding its content.- Overrides:
onDetachedin classWidget<Expander>
-
onAttached
protected void onAttached()Description copied from class:WidgetCalled when this widget enters a scene (attached to the tree).Widget.scene()is the scene it just joined. Fires top-down, so a parent runs before its children. Default no-op.- Overrides:
onAttachedin classWidget<Expander>
-
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). -
clipsChildren
protected boolean clipsChildren()Description copied from class:WidgetWhetherWidget.paintChildren(limn.graphics.Canvas)clips its children to this widget's bounds (scroll views, list viewports, tab strips). Partial rendering uses it to clamp a descendant'sWidget.invalidate()damage to the visible region; a widget scrolled out of view damages nothing. Any override that clips inpaintChildrenshould also override this, and one whose clip is smaller than its box for some child should override the four clip accessors below too.- Overrides:
clipsChildrenin classWidget<Expander>
-
paintChildren
Description copied from class:WidgetChildren pass; override to clip (e.g. scroll views).Indexed rather than an enhanced
for, for the reasonScene's own overlay loop already carries: an iterator here is an allocation per widget per frame, and an idle window is the one place in this toolkit that is not allowed to allocate at all. A subtree of two hundred widgets was paying two hundred short-lived objects a frame to walk a list it can index.- Overrides:
paintChildrenin classWidget<Expander>
-
onAccessibilityChild
Says of the content what only this section knows: that the header names it. A content that said nothing of itself becomes a group, so the link lands on a node; one that already has a role or a name keeps them.- Overrides:
onAccessibilityChildin classWidget<Expander>- Parameters:
child- the child being describeda- the child's node
-