Class Label
wrap, text that does
not fit is cut with a real-measured ellipsis (…), never a blind
character count. With wrap, lines break greedily at the opportunities
BreakIterator finds under the UI language, so
unspaced CJK and dictionary-segmented Thai wrap through the same walk as prose.
Horizontal and vertical alignment supported.
Colors come from the Theme; typography comes from the resolved
ControlSize step, picked by Label.Role.
Geometry comes from one shaping of the paragraph, never from prefix widths.
The width of the first N characters of a string is not the width of anything on screen
once a shaper joins, ligates or reorders, so every question this class asks about where
to cut is asked of a ShapedText: ShapedText.fitEnd(int, float) for the budget and
ShapedText.advanceTo(int) for what a candidate costs. The paragraph shaping does not
depend on the box, so a measure and the layout that follows share it; only the per-line
shapings are width-dependent, and each painted line is re-shaped because
advanceTo is a budget and not a promise about a substring — the forms on
both sides of a cut change when the cut is made.
Content-tight at every step: the measured box is exactly the line box: no minimum height, no padding, and no contribution from the icon. A Label's job beside a Button or a TextField is to let the parent's alignment decide the row height; a floor here would double-count against the container's control height.
The icon overhangs rather than growing the row. Its square is
Strokes.ICON_OPTICAL_BUMP larger than the line box, so measuring
max(lineHeight, iconBox) would let it win unconditionally and leave an icon Label
taller than a bare one; a form column mixing the two goes visibly ragged. The row is the
line box either way and the bump hangs out of the top and bottom, which is what it is
for: icon glyphs carry no ascender/descender slack and must be drawn slightly larger than
the text box to read at the same weight. The overhang is declared to partial rendering by
paintOutset() and drawn outside the text clip.
Reading right to left, the icon and the text swap ends and nothing else moves.
Label.HAlign.START and Label.HAlign.END name where reading starts and ends, so they turn
around with the paragraph; Label.HAlign.CENTER is a centre in either direction and is the one
arm of that decision that is the same number. The icon square is
leading, which is the left edge in one direction and
the right edge in the other, and the glyph inside it turns around only when the call that
placed it said it should — see Icon.Mirroring.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumWhere a line sits in the text region, on two vocabularies that coexist on purpose.static enumstatic enumWhich typographic token the text is drawn with, orthogonal to the size step, which decides how big that token is.static enum -
Constructor Summary
ConstructorsConstructorDescriptionA label showing a fixed string; see theI18nStringconstructor for localized text.Label(I18nString text) A label whose text follows the UI language; seeI18nString. -
Method Summary
Modifier and TypeMethodDescriptionprotected floatDistance from this widget's top edge to its first text baseline, in logical points: the alignment reference forFlex.CrossAlignment.BASELINE.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 voidWidget's own background/content, in local coordinates.protected floatThe icon's optical bump, the only ink a Label puts outside its bounds.role()The typographic role this label draws with.setAlign(Label.HAlign horizontal, Label.VAlign vertical) Alignment of the text block inside the laid-out box.Pins the text colour;nullrestores the theme's, resolved at paint time.Pins an explicit font, overriding both theLabel.Roleand the size step: the escape hatch, and the only thing that beats them.Sets a leading icon, tinted to the text color, drawn as authored whichever way this label reads.setIcon(Icon newIcon, Icon.Mirroring mirroring) Sets a leading icon and says whether its glyph turns around when the interface does.setItalic(boolean newItalic) Italic style on top of the effective font; follows runtime theme switches.setMuted(boolean newMuted) Uses the theme's muted text color, resolved at paint time; unlike an explicitsetColor(limn.graphics.Color), it follows runtime theme switches.setOverflow(Label.Overflow newOverflow) What happens to text wider than the box when wrap is off.setRole(Label.Role newRole) Selects the typographic token; the resolved step decides its size.setStrong(boolean newStrong) Bold weight on top of the effective font; follows runtime theme switches.Replaces the text with a fixed string.setText(I18nString newText) Replaces the text with a value that follows the UI language.setWrap(boolean newWrap) Breaks text across lines at the opportunitiesBreakIteratorreports for the UI language, greedily; a run that offers no opportunity at all — a word longer than the box, or a script this locale has no rule for — is cut at the last cluster that fits.text()The text as it currently reads; seetextSource()for the key behind it.The localizable value this label holds, which a language change re-resolves.Methods inherited from class limn.scene.Widget
acceptsTextInput, add, 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, onKeyEvent, onMouseEvent, onPaintOverlay, onPreedit, overlayPassesPointer, paintChildren, 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
-
Label
A label showing a fixed string; see theI18nStringconstructor for localized text. -
Label
A label whose text follows the UI language; seeI18nString.
-
-
Method Details
-
text
The text as it currently reads; seetextSource()for the key behind it. -
textSource
The localizable value this label holds, which a language change re-resolves. -
setText
Replaces the text with a fixed string. Repaints without a layout pass when the box is unchanged. -
setText
Replaces the text with a value that follows the UI language. UI thread only. -
setFont
Pins an explicit font, overriding both theLabel.Roleand the size step: the escape hatch, and the only thing that beats them. While it is set, the icon box falls back to the font-derived formula, so an explicitly 14 pt label inside an XLARGE subtree does not get a 24 pt icon.nullrestores the role. -
role
The typographic role this label draws with. -
setRole
Selects the typographic token; the resolved step decides its size. Ignored while an explicitsetFont(limn.graphics.Font)is in force. -
setColor
Pins the text colour;nullrestores the theme's, resolved at paint time. -
setMuted
Uses the theme's muted text color, resolved at paint time; unlike an explicitsetColor(limn.graphics.Color), it follows runtime theme switches. -
setStrong
Bold weight on top of the effective font; follows runtime theme switches. -
setItalic
Italic style on top of the effective font; follows runtime theme switches. -
setOverflow
What happens to text wider than the box when wrap is off. -
setAlign
Alignment of the text block inside the laid-out box. -
setWrap
Breaks text across lines at the opportunitiesBreakIteratorreports for the UI language, greedily; a run that offers no opportunity at all — a word longer than the box, or a script this locale has no rule for — is cut at the last cluster that fits. The measured height then depends on the width constraint. UI thread only. -
setIcon
Sets a leading icon, tinted to the text color, drawn as authored whichever way this label reads.nullclears it. Leading is the side reading starts on: the left edge left to right, the right edge right to left. -
setIcon
Sets a leading icon and says whether its glyph turns around when the interface does. The icon's position is leading either way and is this label's decision; whether the drawing inside that square is a back arrow (which turns around) or a logo, a download arrow or a photograph (which must not) is knowable only at the call that placed it, which is why it is a parameter here and not a table anywhere.- Parameters:
newIcon- the icon, ornullto clear itmirroring-Icon.Mirroring.NEVERunless this glyph is directional; a wrongNEVERis one arrow pointing the wrong way, and a wrongIN_RTLis a flipped brand mark
-
baselineOffset
protected float baselineOffset()Description copied from class:WidgetDistance from this widget's top edge to its first text baseline, in logical points: the alignment reference forFlex.CrossAlignment.BASELINE. Defaultheight(): align on the bottom edge, the correct fallback for a widget with no text. Text-bearing components override with the expression they already paint with,(height() - metrics.height()) / 2 + metrics.ascent().Valid only once this widget has been given a box.
Flexguarantees that: it lays every child of a BASELINE line out at cross position 0 first, reads the baselines, then repositions withWidget.moveChild(limn.scene.Widget, float, float), which moves without re-running layout.- Overrides:
baselineOffsetin classWidget
-
paintOutset
protected float paintOutset()The icon's optical bump, the only ink a Label puts outside its bounds. Undeclared, partial rendering would both under-damage the bump onWidget.invalidate()and cull the Label out of a repaint pass that covers only the overhanging sliver, either way leaving a stale crescent of the old glyph on screen.- Overrides:
paintOutsetin classWidget
-
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). -
onPaint
Description copied from class:WidgetWidget's own background/content, in local coordinates.
-