Enum Class LayoutDirection
- All Implemented Interfaces:
Serializable,Comparable<LayoutDirection>,Constable
Mirroring in this toolkit is a placement decision, taken during layout and paint by the widget that owns the coordinate. There is no mirror transform at the canvas root and there must never be one: a global flip would turn correctly shaped text into a mirror image needing a per-run un-flip, would flip every image and every video frame, and would put an inverse transform on the hot path of every hit test.
This enum is the axis only. It carries no numbers and no locale knowledge, so the
toolkit can own it without knowing anything about text, which is what lets a raw
Row act as a direction scope for the components inside it. It is the
companion of ControlSize, resolved by the same chain, invalidated by its own epoch, and
read under the same two rules.
The coexistence contract
A widget's direction is inherited down the tree: its own declared value, else the nearest declaring ancestor's, else its scene's default, else its host's, elseprocessDefault().
LTR is the process default and mirroring is opt-in per subtree, which is what makes
a Hebrew interface holding a left-to-right code editor, log pane, URL bar or JSON viewer
expressible: each of those is a subtree that reads one way inside an interface that reads the
other, and a direction derived from a process-wide locale could not say so. An application in
Arabic writes one line at its scene root; a subtree that disagrees writes one more.
This is never read from the locale
Nothing in the toolkit consultsI18n.locale() to decide a direction. Language and
direction are different axes: a Hebrew subtree inside an English interface still shows English
strings, it just lays them out right to left. forLocale(java.util.Locale) exists so an application
can bridge the two at its own call site, typically once at startup; it is not called by the
toolkit and must not be called from inside a widget, where it would smuggle the process locale
back into the axis this enum exists to keep out of it.
Never read this in a constructor
Widget.add(limn.scene.Widget) assigns the child's parent after the child is fully constructed, so
new Button("OK") runs with no parent and resolves to the process default whatever its
eventual parent declares. A direction captured at construction is permanently wrong with no path
to recovery, exactly as a captured ControlSize is.
Read it in onMeasure, onPaint, onLayout or an event handler, where the
tree is complete, and resolve it once per pass into a local: two resolutions that disagree
inside one onPaint put the caret on one side and the selection band on the other.
What a direction change does to a held value
A paragraph's base direction decides which bidi level a boundary neutral takes, which decides which run it extends, which decides which face measures it. A line of mixed content therefore measures a fraction of a point differently in the two directions. The amount is one face's disagreement about a space per neutral at the paragraph's edge — an interior neutral does not move at all — so it is small on any real line, and it is nonetheless enough to make a heldShapedText and a cached measurement both stale across a change —
which is why ShapedText.matches(java.lang.String, limn.graphics.Font, limn.graphics.ShapedText.Direction, limn.graphics.TextRuler) takes a direction and why
Widget.measure(limn.scene.Constraints) keys its cache on the resolved one.- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from class java.lang.Enum
Enum.EnumDesc<E extends Enum<E>> -
Enum Constant Summary
Enum Constants -
Method Summary
Modifier and TypeMethodDescriptionstatic voidaddChangeListener(Runnable listener) Subscribes to process-default changes (idempotent per instance).static LayoutDirectionMaps a locale to the direction its script is normally written in: the bridge betweenI18nand this axis, offered so that an application can writeLayoutDirection.setProcessDefault(LayoutDirection.forLocale(locale))at startup instead of writing the same table itself.booleanopposite()static LayoutDirectionstatic voidremoveChangeListener(Runnable listener) Unsubscribes; no-op when it was never registered.static voidsetProcessDefault(LayoutDirection direction) Sets the process-wide fallback direction: the root of the inheritance chain, and the one line an application that is entirely right to left writes at startup.static LayoutDirectionReturns the enum constant of this class with the specified name.static LayoutDirection[]values()Returns an array containing the constants of this enum class, in the order they are declared.
-
Enum Constant Details
-
LTR
Left to right: the default, and what every existing Limn UI renders as. -
RTL
Right to left: Arabic, Hebrew, Persian, Urdu and the rest of the right-to-left scripts.
-
-
Method Details
-
values
Returns an array containing the constants of this enum class, in the order they are declared.- Returns:
- an array containing the constants of this enum class, in the order they are declared
-
valueOf
Returns the enum constant of this class with the specified name. The string must match exactly an identifier used to declare an enum constant in this class. (Extraneous whitespace characters are not permitted.)- Parameters:
name- the name of the enum constant to be returned.- Returns:
- the enum constant with the specified name
- Throws:
IllegalArgumentException- if this enum class has no constant with the specified nameNullPointerException- if the argument is null
-
opposite
- Returns:
- the opposite direction;
LTR.opposite() == RTL
-
isRightToLeft
public boolean isRightToLeft()- Returns:
- whether this is
RTL, for thedir == RTLtests that fill widgets
-
processDefault
- Returns:
- the direction used where nothing in the tree and no scene declares one
-
setProcessDefault
Sets the process-wide fallback direction: the root of the inheritance chain, and the one line an application that is entirely right to left writes at startup. Every live scene re-measures, overlays included and unbound scenes included; widgets and scenes that declare their own direction are unaffected. No-op when unchanged. UI thread only. -
addChangeListener
Subscribes to process-default changes (idempotent per instance). -
removeChangeListener
Unsubscribes; no-op when it was never registered. -
forLocale
Maps a locale to the direction its script is normally written in: the bridge betweenI18nand this axis, offered so that an application can writeLayoutDirection.setProcessDefault(LayoutDirection.forLocale(locale))at startup instead of writing the same table itself.Nothing in the toolkit calls this, and a widget that calls it has reintroduced the process-wide locale as a source of direction, which is the one thing this axis exists to prevent. It is a function from a locale to a direction, at an application's call site, and a starting point rather than a policy: an application whose user has chosen a direction should honour that choice instead.
The script is consulted first and the language only when the locale names no script, because a language can be written in either. Anything unrecognised is
LTR, which is the same fallback the first-strong rule makes for text with no strong character.- Parameters:
locale- the locale to classify- Returns:
RTLwhen that locale's script is written right to left, elseLTR- Throws:
NullPointerException- iflocaleis null
-