Class Transform
A container, as Padding is for space round a child and Opacity for a fade:
the cost is only where the container is, and the order of two effects on one child is the order
their containers are nested in. To fade a moving child, new Opacity(new Transform(child))
reads as "fade this moving thing" and draws the same picture as the other order.
The values, each with its default at rest:
- a translation,
setTranslation(float, float), in points:xtoward the end of the layout direction (right in a left-to-right subtree, left in a right-to-left one),ydown;(0, 0); - a rotation,
setRotation(float), in degrees clockwise on the screen, the same way in either direction, as a clock turns;0; - a scale,
setScale(float, float): a negative factor mirrors, and a factor of 0 collapses the child to a line or a point, which then draws nothing and is out of reach (below);(1, 1); - a general matrix,
setMatrix(limn.math.Mat4), for a skew or any other map the other values do not name; the identity; - an origin,
setOrigin(float, float): the point a rotation, a scale, the matrix, a turn in depth and a flip keep still, as fractions of the box measured from its start edge and its top, so that a scale that grows from the start grows toward the end in either direction;(0.5, 0.5).
- a turn in depth,
setRotation3D(Vec3, float), about an axis through the origin; none; - a perspective,
setPerspective(float): how far in front of the origin the eye is, so that the near edge of a turned child is drawn larger than the far one; none, infinitely far, by default, which draws a turn about the vertical axis as a narrowing; - whether the child is drawn while its back is turned to the viewer,
setBackfaceVisible(boolean); it is.
Transparent to everything but where its child is drawn. It measures, lays out and aligns on a baseline as its child alone does, the child given its whole box; it paints nothing of its own, takes no focus, and has no node of its own in the accessible tree, which holds the child in its place. It does not clip: what the child draws past the box is seen there, and a transform that should be cut goes inside a container that clips. It is hit only where its child is drawn, inside its box or past it, so the place a child slid away from takes the pointer from what is beneath.
A child drawn as nothing is out of reach, as a hidden one is. Collapsed by a scale of 0
on either axis, turned exactly edge-on, or showing its back while back
faces are hidden, the child and everything inside it are not showing: the
Tab key, an access letter and the pointer pass them by, the focus, the hover and a press held
there are taken out of them, with the events a widget hidden by Widget.setVisible(boolean) is sent,
inside the set that does it, or once the frame of a motion that does it has stepped every
motion, or once the layout pass that does it (a new box tipping a plane past edge-on) is over,
and a screen reader is told they are hidden. A popover or a list open from a control in
them closes, as an adjustment, before the focus is taken out, and none opens from one. They come
back by themselves, in reach and published again, when the scale returns or the face turns
back; the focus they lost is not given back. Nothing of the child's own state changes, and
Widget.isVisible() still answers what it was told.
What it costs: nothing at rest, where the frame is the frame without it. Moved or
scaled, the child is drawn straight into the window, moved and scaled, every clip inside it exact;
a change repaints where the child was and where it is, and lays nothing out. A uniform scale
keeps text crisp; a scale animation draws the glyphs again at each size it passes through.
Rotated or skewed, the child is drawn upright into a picture of its own, at the size it is seen
at, and the picture is laid at the angle: every clip inside stays an exact rectangle, a view
scrolled inside still skips what scrolled away, the edges are smoothed over about a pixel, and
text reads slightly softer, as text at an angle does. A frosted glass inside reads the window
behind as it would upright. The picture costs what an Opacity container's fade costs a
frame of the same size; it is made again whenever something inside repaints while the child is
turned, and given back the frame after the child comes to rest upright. Turned in depth, the
picture is laid in perspective and drawn at the size of its nearest edge, so it stays sharp
there, and text far from the eye reads softer; on a computer with no graphics processor, where
every pixel of a picture costs processor time, it is drawn at the child's own size instead, and
the near edge reads a little softer too. Where the picture is seen at less than half its size,
a page turned far back, its detail is averaged rather than left to flicker while it turns. What
part of a child passes behind the eye is not drawn, and the rest is. A frosted glass inside a
child seen in perspective reads only what the child draws beneath it, not the window. Something
inside that draws in a blend mode, a tint in
BlendMode.MULTIPLY, blends with the picture while the child is turned, and
where the child drew nothing beneath it is drawn as itself; at rest, or only moved and scaled,
there is no picture and it blends with what is beneath the container.
A watcher hears it as Change.Aspect.TRANSFORM with origin CODE on this
container: every time a set changes a value, once for reset(), and twice for a motion,
as it starts and as it arrives or is superseded. A screen reader is told where the child is when a
value is set and when a motion arrives, and not on the frames between: its highlight jumps to
where the child came to rest.
Every setter and motion is fluent and UI thread only, refuses NaN and the infinities
with IllegalArgumentException, and is refused from inside a paint, which is re-run per
pass and must not move what it paints.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumWhich wayflipToturns the child over: two about the vertical axis that follow the reading direction, and two about the horizontal axis that do not. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected floatThe child's: the container aligns on a baseline as the child alone does.flipTo(Transform.Flip direction, double seconds, Runnable atEdge, @Nullable Runnable onArrive) Turns the child over and back overseconds: from flat to edge-on about the axisdirectionnames, where it runsatEdge, and from edge-on on the other side back to flat, so that whatatEdgeput in the child arrives the right way round.flipTo(Transform.Flip direction, Runnable atEdge) flipTo(Flip, double, Runnable, Runnable)over the theme's window animation, with nothing run at the end.booleanmatrix()protected @Nullable Widget<?> onHitTest(float localX, float localY) The child where it is drawn, or nothing: never this container, which is only a place.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.floatoriginX()floatoriginY()protected floatHow far the child, with its own reach, is drawn past this box: its own declared reach at rest, as anOpacitycontainer declares, and where the transform puts it otherwise, a drawer slid past the box or a card scaled up, so that a repaint of that band reaches it.floatreset()Puts every value back at rest, the origin included, and stops every motion in flight, as one change: a watcher hears it once, besides the end of each motion it superseded.rotateTo(float degrees) rotateTo(float, double, Runnable)over the theme's window animation, with nothing run at the end.Moves therotationtodegreesoverseconds, by the rulesslideTostates: eased, on the one ticker beside a slide and a scale, straight there under less motion withonArriveafter its seconds and never inside this call, superseded by a newer rotation or asetRotation(float), settled as the container leaves its scene, and heard twice.floatrotation()scaleTo(float s) scaleTo(float, float, double, Runnable)toson both axes over the theme's window animation, with nothing run at the end.Moves thescaleto(sx, sy)overseconds, by the rulesslideTostates: eased, on the one ticker, straight there under less motion withonArriveafter its seconds and never inside this call, superseded by a newer scale or asetScale(float), settled as the container leaves its scene, and heard twice.floatscaleX()floatscaleY()setBackfaceVisible(boolean visible) Sets whether the child is drawn, and hit, while its plane shows the viewer its back: turned past ninety degrees out of the screen.Sets a general matrix the child is drawn through, about theorigin, before the scale and the turns: a skew, or any map the other values do not name.setOrigin(float fractionX, float fractionY) Sets the point a scale and a flip keep still, as fractions of the box:fractionXfrom the start edge (the left in a left-to-right subtree, the right in a right-to-left one),fractionYfrom the top.setPerspective(float distance) Looks at the child fromdistancepoints in front of theorigin, at once: a turned child's near edge is drawn larger than its far one, as a card held up and turned is seen.setRotation(float degrees) Turns the child bydegreesclockwise on the screen about theorigin, at once.setRotation3D(Quat turn) Turns the child's plane byturn, through theorigin, at once, in the canvas's axes assetRotation3D(Vec3, float)names them: for a turn composed of several, or one kept from another rotation.setRotation3D(Vec3 axis, float degrees) Turns the child's plane bydegreesaboutaxis, through theorigin, at once: out of the screen, so that one edge comes toward the viewer and the opposite one goes away.setScale(float s) Scales the child byson both axes about theorigin, at once.setScale(float sx, float sy) setTranslation(float x, float y) Moves the child by(x, y)points, at once.slideTo(float x, float y) slideTo(float, float, double, Runnable)over the theme's window animation, the time the toolkit's own popups and dialogs move in, with nothing run at the end.Moves thetranslationto(x, y)overseconds, eased as the toolkit eases a fade, one step a frame on the scene's wall-time ticker, which ticks only while something moves and which pausing the scene does not freeze.floatfloatMethods inherited from class limn.scene.Widget
acceptsTextInput, accessibleLabelAccessKey, accessibleLabelTarget, accessibleLabelText, add, add, announceChange, backdropReach, baselineOffsetOf, caretRect, children, clipboard, clipHeight, clipsChildren, clipWidth, clipX, clipY, controlSize, cursor, declaredControlSize, declaredLayoutDirection, declaredLocale, focusArrivedBackward, focusArrivedByTraversal, handleUserChange, 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, onAccessibilityChild, onAccessibilityChildAction, onAccessibilityChildIdentity, onAttached, onCanEdit, onCharTyped, onDetached, onDragExit, onDragOver, onDragStart, onDrop, onEdit, onFocusGained, onFocusLost, onKeyEvent, onMouseEvent, onPaint, onPaintOverlay, onPreedit, onSyntheticAction, overlayPassesPointer, paintChildren, 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
-
Transform
Wrapschildat rest: drawn where layout puts it.- Parameters:
child- the widget this container draws moved, scaled or flipped
-
-
Method Details
-
setTranslation
Moves the child by(x, y)points, at once.xruns toward the end of the layout direction, so a drawer that slides in from the end edge is the same line in either direction, andyruns down. Aslidein flight is superseded: it stops where it is, announces its end, and itsonArrivenever runs; nor does that of one gone straight there that still waits.- Parameters:
x- toward the end, in pointsy- down, in points- Returns:
- this
- Throws:
IllegalArgumentException- if either isNaNor infiniteIllegalStateException- off the UI thread, or from inside a paint
-
translationX
public float translationX()- Returns:
- the translation toward the end, in points
-
translationY
public float translationY()- Returns:
- the translation down, in points
-
setScale
Scales the child byson both axes about theorigin, at once.- Parameters:
s- the factor; negative mirrors, 0 collapses the child to a point- Returns:
- this
- Throws:
IllegalArgumentException- if it isNaNor infiniteIllegalStateException- off the UI thread, or from inside a paint- See Also:
-
setScale
Scales the child bysxalong x andsyalong y about theorigin, at once. Ascalein flight is superseded. A uniform scale keeps text crisp; two different factors draw it softer while they last. A factor of 0 on either axis draws the child as nothing and takes the keyboard focus out of it, as hiding it would (see the class's note).- Parameters:
sx- the factor along x; negative mirrors, 0 collapses the child to a linesy- the factor along y- Returns:
- this
- Throws:
IllegalArgumentException- if either isNaNor infiniteIllegalStateException- off the UI thread, or from inside a paint
-
scaleX
public float scaleX()- Returns:
- the scale along x
-
scaleY
public float scaleY()- Returns:
- the scale along y
-
setOrigin
Sets the point a scale and a flip keep still, as fractions of the box:fractionXfrom the start edge (the left in a left-to-right subtree, the right in a right-to-left one),fractionYfrom the top.(0.5, 0.5), the middle, by default;(0, 0)grows the child from its start corner. A fraction outside 0 to 1 puts the point outside the box, which is allowed.- Parameters:
fractionX- from the start edgefractionY- from the top- Returns:
- this
- Throws:
IllegalArgumentException- if either isNaNor infiniteIllegalStateException- off the UI thread, or from inside a paint
-
originX
public float originX()- Returns:
- the origin's fraction of the box from its start edge
-
originY
public float originY()- Returns:
- the origin's fraction of the box from its top
-
setRotation
Turns the child bydegreesclockwise on the screen about theorigin, at once. Physical: a right-to-left subtree turns the same way, as a clock does. Arotationin flight is superseded. The child is drawn through a picture while it is turned (see the class's note on what it costs); a whole turn of 360 degrees draws it upright, through the picture still.- Parameters:
degrees- clockwise on the screen- Returns:
- this
- Throws:
IllegalArgumentException- if it isNaNor infiniteIllegalStateException- off the UI thread, or from inside a paint
-
rotation
public float rotation()- Returns:
- the rotation, in degrees clockwise on the screen
-
setMatrix
Sets a general matrix the child is drawn through, about theorigin, before the scale and the turns: a skew, or any map the other values do not name. The child lies in the planez = 0, so a point(x, y)of it, taken from the origin, goes through the matrix as(x, y, 0, 1)and is drawn at its x and y divided by its w; the z row matters through a turn in depth and theperspective, which see the depth it gives, and a bottom row that changes w draws the child in a perspective of the matrix's own. Physical, as the rotation is. The identity is no matrix.Mat4.affine2D(float, float, float, float, float, float)makes one from the six numbers of a 2D affine map, andMat4.perspectiveAt(float)a perspective.- Parameters:
matrix- the matrix- Returns:
- this
- Throws:
NullPointerException- if it is nullIllegalArgumentException- if an entry isNaNor infiniteIllegalStateException- off the UI thread, or from inside a paint
-
matrix
- Returns:
- the general matrix,
Mat4.IDENTITYwhen none is set
-
setRotation3D
Turns the child's plane bydegreesaboutaxis, through theorigin, at once: out of the screen, so that one edge comes toward the viewer and the opposite one goes away. The axes are the canvas's: x to the right, y down, z out of the screen toward the viewer. A positive angle about z turns assetRotation(float)does, clockwise; about y the right edge goes away from the viewer and the left comes toward it; about x the bottom edge comes toward the viewer and the top goes away. Physical, as the rotation is: a right-to-left subtree turns the same way.With no
perspectivea turn about y narrows the child, and one past ninety degrees shows its back, mirrored. A turn of exactly ninety degrees out of the screen leaves the child edge-on: it draws nothing and is out of reach, as the class's note says of a child drawn as nothing. A whole turn is no turn.- Parameters:
axis- the axis, of any length but 0degrees- the angle, in degrees, the way the paragraph above says for each axis; about any other axis, as a quaternion of that axis and angle turns- Returns:
- this
- Throws:
NullPointerException- ifaxisis nullIllegalArgumentException- if a component or the angle isNaNor infinite, or the axis has no lengthIllegalStateException- off the UI thread, or from inside a paint
-
setRotation3D
Turns the child's plane byturn, through theorigin, at once, in the canvas's axes assetRotation3D(Vec3, float)names them: for a turn composed of several, or one kept from another rotation. Normalized, so a quaternion of any length but 0 names its turn; of the two quaternions that name one turn,rotation3D()answers the one whosewis not below 0.Quat.IDENTITYis no turn.- Parameters:
turn- the turn- Returns:
- this
- Throws:
NullPointerException- if it is nullIllegalArgumentException- if a component isNaNor infinite, or all are 0IllegalStateException- off the UI thread, or from inside a paint
-
rotation3D
- Returns:
- the turn in depth, a unit quaternion,
Quat.IDENTITYwhen there is none
-
setPerspective
Looks at the child fromdistancepoints in front of theorigin, at once: a turned child's near edge is drawn larger than its far one, as a card held up and turned is seen. Two to four times the larger side of the box is the usual look; nearer is more dramatic, farther flatter. The vanishing point is the origin, and thetranslationmoves it with what it sees. The perspective changes nothing of a child whose plane faces the viewer squarely: only a turn in depth, a flip or a matrix that gives the plane depth is seen through it.Float.POSITIVE_INFINITY, the default, is no perspective. A part of the child that a turn brings past the eye is not drawn, and the rest is.- Parameters:
distance- how far the eye is, in points, above 0; infinite for none- Returns:
- this
- Throws:
IllegalArgumentException- if it is not above 0, or isNaNIllegalStateException- off the UI thread, or from inside a paint
-
perspective
public float perspective()- Returns:
- how far the eye is in front of the origin, in points; infinite for no perspective
-
setBackfaceVisible
Sets whether the child is drawn, and hit, while its plane shows the viewer its back: turned past ninety degrees out of the screen. Drawn by default, mirrored as the back of a pane of glass is; hidden, a turned-over child draws nothing and is out of reach as a hidden child is (see the class's note): not showing, passed by the Tab key and the pointer, the focus taken out of it, published hidden, until it turns back. A child mirrored by a negativescalestill faces the viewer and is drawn either way.This is how two faces show one at a time without a swap: a
Stackof two containers with the same perspective and back faces hidden, the back turned half a turn further than the front, both turned together. At every angle exactly one face is drawn, is showing and takes the keyboard and the pointer, the one turned toward the viewer, but at exactly ninety degrees from flat, where both planes lie along the line of sight and neither is drawn: for that one angle neither face is showing or in reach. A focus held in the face that turns away is lost as it turns.- Parameters:
visible- whether a back face is drawn and hit- Returns:
- this
- Throws:
IllegalStateException- off the UI thread, or from inside a paint
-
isBackfaceVisible
public boolean isBackfaceVisible()- Returns:
- whether the child is drawn and hit while its back is turned to the viewer
-
reset
Puts every value back at rest, the origin included, and stops every motion in flight, as one change: a watcher hears it once, besides the end of each motion it superseded. The callbacks of a motion gone straight there that still wait never run either.- Returns:
- this
- Throws:
IllegalStateException- off the UI thread, or from inside a paint
-
slideTo
slideTo(float, float, double, Runnable)over the theme's window animation, the time the toolkit's own popups and dialogs move in, with nothing run at the end.- Parameters:
x- toward the end, in pointsy- down, in points- Returns:
- this
- Throws:
IllegalArgumentException- if either isNaNor infiniteIllegalStateException- off the UI thread, or from inside a paint
-
slideTo
Moves thetranslationto(x, y)overseconds, eased as the toolkit eases a fade, one step a frame on the scene's wall-time ticker, which ticks only while something moves and which pausing the scene does not freeze. One ticker per container, whatever the number of motions asked for; a slide and ascalerun together.Straight to the target, as one
setTranslation(float, float), while the system asks for less motion, for no time, for the translation the container already has, or with no frames to step it: a container in no scene, or in a scene with no window. ItsonArriveruns then after thesecondsasked for, as a taskUi.postDelayed(java.lang.Runnable, long)runs, so that what follows it keeps the pace the call asked for; for no time, on the next turn of the UI thread's queue.onArrivenever runs inside this call, whether the slide moves or goes straight there, so the next step of a sequence, or of motion that repeats, can be asked for in it. Such a chain keeps the pace its calls ask for, where the motions go straight there too, and the UI thread sleeps between its steps. It goes on, one step a period whether the container is shown or not, for as long as the code keeps asking, so repeating motion stops itself: when what it stands for is over, or when its container is no longershowing.A newer slide or a
setTranslation(float, float)supersedes one in flight, or one gone straight there whoseonArrivestill waits: it stops where it is, and itsonArrivenever runs. A slide on a container that leaves its scene settles at its target as it leaves and runs itsonArrivethen, as does one that went straight there and still waits for its seconds (a flip's swap first, if it has not run). Both run once the container is out of the scene it left, so a motion they ask for follows the container: straight there when it is in no scene, or on the frames of the scene it went to, never on those of the window it left, and after the change that took it out has done all its own work. A callback that throws, on a frame or as its container leaves, is logged and reported as a throwing ticker is, and changes nothing for the motions beside it, the container's later ones, one it asked for before it threw, or the change.A watcher hears it twice, as
Change.Aspect.TRANSFORM: when it starts, and when it arrives or is superseded. The frames between repaint without announcing and without telling a screen reader, which hears where the child is when it arrives.- Parameters:
x- toward the end, in pointsy- down, in pointsseconds- how long it takes, when the system does not ask for less motiononArrive- run once when it arrives, or aftersecondswhen it goes straight there (on the next turn of the UI thread's queue for none); never inside this call, never when it is superseded; may be null- Returns:
- this
- Throws:
IllegalArgumentException- ifxoryisNaNor infinite, orsecondsis negative,NaNor infiniteIllegalStateException- off the UI thread, or from inside a paint
-
scaleTo
scaleTo(float, float, double, Runnable)toson both axes over the theme's window animation, with nothing run at the end.- Parameters:
s- the factor to arrive at- Returns:
- this
- Throws:
IllegalArgumentException- if it isNaNor infiniteIllegalStateException- off the UI thread, or from inside a paint
-
scaleTo
Moves thescaleto(sx, sy)overseconds, by the rulesslideTostates: eased, on the one ticker, straight there under less motion withonArriveafter its seconds and never inside this call, superseded by a newer scale or asetScale(float), settled as the container leaves its scene, and heard twice. The glyphs of the text inside are drawn again at each size the scale passes through.A scale that arrives at 0 on either axis draws the child as nothing and puts it out of reach as a hidden child is (see the class's note): it loses the keyboard focus, which is not given back when the scale returns. A motion arrives exactly at its target, so a card turned over by hand, scaled to 0 across, swapped and scaled back, always loses the focus it held;
flipToturns a card over and keeps it. A motion that only passes 0 on its way, from 1 to −1, keeps it: its frames between do not land on 0.- Parameters:
sx- the factor along x to arrive atsy- the factor along y to arrive atseconds- how long it takes, when the system does not ask for less motiononArrive- run once when it arrives, or aftersecondswhen it goes straight there (on the next turn of the UI thread's queue for none); never inside this call, never when it is superseded; may be null- Returns:
- this
- Throws:
IllegalArgumentException- if a factor isNaNor infinite, orsecondsis negative,NaNor infiniteIllegalStateException- off the UI thread, or from inside a paint
-
rotateTo
rotateTo(float, double, Runnable)over the theme's window animation, with nothing run at the end.- Parameters:
degrees- the rotation to arrive at, clockwise on the screen- Returns:
- this
- Throws:
IllegalArgumentException- if it isNaNor infiniteIllegalStateException- off the UI thread, or from inside a paint
-
rotateTo
Moves therotationtodegreesoverseconds, by the rulesslideTostates: eased, on the one ticker beside a slide and a scale, straight there under less motion withonArriveafter its seconds and never inside this call, superseded by a newer rotation or asetRotation(float), settled as the container leaves its scene, and heard twice. It turns the short way or the long way as the numbers say: from 350 to 10 degrees is 340 degrees back, and to 370 is twenty forward.- Parameters:
degrees- the rotation to arrive at, clockwise on the screenseconds- how long it takes, when the system does not ask for less motiononArrive- run once when it arrives, or aftersecondswhen it goes straight there (on the next turn of the UI thread's queue for none); never inside this call, never when it is superseded; may be null- Returns:
- this
- Throws:
IllegalArgumentException- ifdegreesisNaNor infinite, orsecondsis negative,NaNor infiniteIllegalStateException- off the UI thread, or from inside a paint
-
flipTo
flipTo(Flip, double, Runnable, Runnable)over the theme's window animation, with nothing run at the end.- Parameters:
direction- which way the child turns overatEdge- run with the child edge-on, where it swaps what it shows- Returns:
- this
- Throws:
NullPointerException- if either is nullIllegalStateException- off the UI thread, or from inside a paint
-
flipTo
public Transform flipTo(Transform.Flip direction, double seconds, Runnable atEdge, @Nullable Runnable onArrive) Turns the child over and back overseconds: from flat to edge-on about the axisdirectionnames, where it runsatEdge, and from edge-on on the other side back to flat, so that whatatEdgeput in the child arrives the right way round. The place to hide one face and show the other: a card's front and back are two children of aStackinside this container, andatEdgeswaps which is visible.Drawn flat while no
perspectiveis set: the child narrows to a line about theoriginand widens back, which is cheap and needs nothing but a scale; text is softer while it turns and crisp again at the end. With a perspective it turns in depth, the edge coming over growing toward the viewer, through a picture while it turns. Either way it turns the child as it appears, after its own turn in depth and rotation, and leaves every value as it found it. A frame that lands exactly edge-on draws the child as nothing, which puts it out of reach for that frame (see the class's note); the faceatEdgehides loses the focus asWidget.setVisible(boolean)takes it from any widget.By the rules of
slideTo: eased over the whole turn, fastest edge-on; on the one ticker beside a slide and a scale; superseded by a newer flip, which turns on from wherever this one had got to and runs its ownatEdge, or byreset(); settled as the container leaves its scene,atEdgefirst if the edge was not reached; heard twice. While the system asks for less motion, for no time, or with no frames to step it, there is no turn at all:atEdgeruns on the next turn of the UI thread's queue, so the content changes at once and with no transition, andonArriveafterseconds(with the swap, for none). Two flips asked for some way apart therefore swap twice, as they do when the first is past its edge as the second comes. A newer flip or areset()before the swap supersedes both; after it, the swap stays made and only the waitingonArriveis dropped; and a flip that its ownatEdgesupersedes does not arrive. Neither runs inside this call, in any case.- Parameters:
direction- which way the child turns overseconds- how long the whole turn takes, when the system does not ask for less motionatEdge- run once, with the child edge-on, or on the next turn with no turn at all; never inside this callonArrive- run once when the child is flat again, or aftersecondswith no turn at all; never inside this call, never when it is superseded; may be null- Returns:
- this
- Throws:
NullPointerException- ifdirectionoratEdgeis nullIllegalArgumentException- ifsecondsis negative,NaNor infiniteIllegalStateException- off the UI thread, or from inside a paint
-
paintOutset
protected float paintOutset()How far the child, with its own reach, is drawn past this box: its own declared reach at rest, as anOpacitycontainer declares, and where the transform puts it otherwise, a drawer slid past the box or a card scaled up, so that a repaint of that band reaches it. Computed from the child's corners on asking, which is constant-time.- Overrides:
paintOutsetin classWidget<Transform>
-
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). -
baselineOffset
protected float baselineOffset()The child's: the container aligns on a baseline as the child alone does.- Overrides:
baselineOffsetin classWidget<Transform>
-
onHitTest
The child where it is drawn, or nothing: never this container, which is only a place.
-