-
Notifications
You must be signed in to change notification settings - Fork 0
Styling
Every component takes a Style (immutable) that controls size, spacing, color, font, border, alignment, opacity, and click handling. Styles are built with a fluent Style.Builder; static factories on Style and Styles give you a head start.
import org.triggersstudio.moddinglib.client.ui.styling.Style;
import org.triggersstudio.moddinglib.client.ui.styling.Styles;
Style s = Style.builder()
.width(120).height(28)
.padding(4, 8)
.backgroundColor(0xFF_2A_2A_2A)
.textColor(0xFF_FF_FF_FF)
.border(0xFF_55_55_55, 1)
.borderRadius(4)
.build();Or with the static-import helpers:
import static org.triggersstudio.moddinglib.client.ui.styling.Styles.*;
Style s = padding(4, 8)
.width(120).height(28)
.backgroundColor(0xFF_2A_2A_2A)
.textColor(WHITE)
.border(0xFF_55_55_55, 1)
.borderRadius(4)
.build();Style.DEFAULT is the no-op style: WRAP_CONTENT size, white text, 9pt font, no background, no border, fully opaque.
Every method returns the builder for chaining. Call .build() at the end.
| Method | Notes |
|---|---|
width(int) / height(int)
|
Accepts Size.WRAP_CONTENT (-1), Size.MATCH_PARENT (-2), or a positive pixel count. |
padding(int all) |
Same on every side. |
padding(int vertical, int horizontal) |
Top/bottom = vertical, left/right = horizontal. |
padding(int top, int right, int bottom, int left) |
Per-side. |
margin(...) |
Same overloads. |
backgroundColor(int color) |
ARGB. 0x00_00_00_00 = transparent. |
textColor(int color) |
ARGB. Default 0xFF_FF_FF_FF. |
fontSize(float) |
Default 9f. |
borderRadius(int) |
Corner rounding in pixels. Clamped to min(width, height) / 2. |
border(int color, int width) |
Shorthand for color + width. |
align(Alignment h, Alignment v) |
Text/content alignment. |
onClick(ClickHandler) |
(double x, double y, int button) -> void. |
opacity(float) |
Clamped to [0, 1]. |
bold() |
Bold text (renders via Minecraft's bold formatting). |
placeholderColor(int) |
TextField/TextArea placeholder color. 0 = derive from textColor at reduced alpha. |
font(Identifier) |
Render text with a Minecraft resource-pack font. See Custom fonts. |
background(Paint) |
Solid or gradient fill for the component background. See Paint and gradients. |
textFill(Paint) |
Solid or gradient fill applied per-glyph to text. See Paint and gradients. |
Style.toBuilder() returns a builder pre-populated with the style's current values, so you can derive variants without restating everything.
Each one creates a builder with that property set, so you can drop .builder() from one-liners:
Style.width(60).height(20).build()
Style.padding(8).backgroundColor(0xFF_22_22_22).build()
Style.border(0xFF_55_55_55, 1).borderRadius(4).build()Available: width, height, padding, margin, backgroundColor, textColor, fontSize, borderRadius, border, align, onClick, opacity, bold, placeholderColor, font, background, textFill.
org.triggersstudio.moddinglib.client.ui.styling.Styles re-exports the static factories plus a few constants. Import statically and you don't need the Style. prefix:
import static org.triggersstudio.moddinglib.client.ui.styling.Styles.*;WRAP_CONTENT // -1
MATCH_PARENT // -2START CENTER END STRETCHBLACK = 0xFF_00_00_00
WHITE = 0xFF_FF_FF_FF
RED = 0xFF_FF_00_00
GREEN = 0xFF_00_FF_00
BLUE = 0xFF_00_00_FF
TRANSPARENT = 0x00_00_00_00size(int width, int height) plus the same factory list as on Style (width, height, padding, margin, backgroundColor, textColor, fontSize, borderRadius, border, align, onClick, opacity, bold, placeholderColor, font, background, textFill).
Used internally by padding(...) and margin(...). You rarely instantiate one yourself.
new Insets(int all)
new Insets(int vertical, int horizontal)
new Insets(int top, int right, int bottom, int left)
insets.getHorizontal() // left + right
insets.getVertical() // top + bottom
Insets.ZERO // no inset constantpublic enum Alignment { START, CENTER, END, STRETCH }Used for text alignment in Text and content alignment in containers when the cross-axis has free space.
Layout sentinels:
Size.WRAP_CONTENT // -1
Size.MATCH_PARENT // -2
Size.isWrapContent(int)
Size.isMatchParent(int)
Size.isFixed(int)The builder defaults match Style.DEFAULT:
| Property | Default |
|---|---|
| width / height | WRAP_CONTENT |
| padding / margin | Insets.ZERO |
| backgroundColor |
0x00_00_00_00 (transparent) |
| textColor |
0xFF_FF_FF_FF (white) |
| fontSize | 9f |
| borderRadius | 0 |
| borderColor | 0xFF_00_00_00 |
| borderWidth | 0 |
| horizontalAlignment | Alignment.START |
| verticalAlignment | Alignment.START |
| clickHandler | null |
| opacity | 1.0f |
| bold | false |
| placeholderColor |
0 (derive from textColor) |
| font |
null (vanilla font) |
| backgroundPaint |
null (derive from backgroundColor) |
| textPaint |
null (derive from textColor) |
Paint is a sealed interface that describes how a region should be filled — either a single ARGB color or a multi-stop gradient. It plugs into both Style.background(Paint) (component backgrounds) and Style.textFill(Paint) (per-glyph text gradients).
import org.triggersstudio.moddinglib.client.ui.styling.Paint;| Variant | What it does |
|---|---|
Paint.Solid(int argb) |
Single ARGB color. |
Paint.LinearGradient(double angleDegrees, List<Stop>) |
Sweep along a straight axis. 0° = left → right, 90° = top → bottom. |
Paint.RadialGradient(double cx, double cy, double rx, double ry, List<Stop>) |
Disc/ellipse from a fractional center point (cx, cy) ∈ [0,1]². rx, ry are radii as fractions of the rect's width / height. |
Paint.ConicGradient(double cx, double cy, double startAngleDegrees, List<Stop>) |
360° clockwise sweep around (cx, cy). |
A color anchor along the gradient. Offset is in [0, 1]; multiple stops give multi-color gradients.
Paint.stop(double offset, int argb)Paint.solid(int argb)
Paint.linear(double angleDeg, int from, int to) // two-color shorthand
Paint.linear(double angleDeg, Paint.Stop... stops) // multi-stop
Paint.radial(int from, int to) // centered, full disc
Paint.radial(double cx, double cy, double rx, double ry, Paint.Stop... stops)
Paint.conic(double startAngleDeg, Paint.Stop... stops) // centered
Paint.conic(double cx, double cy, double startAngleDeg, Paint.Stop... stops)Stops do not need to be passed in order — Paint sorts them on construction. Two stops minimum for any gradient.
Linear, multi-stop, custom angle:
Paint sunset = Paint.linear(45,
Paint.stop(0.0, 0xFF_FF_55_55),
Paint.stop(0.4, 0xFF_FF_DD_55),
Paint.stop(1.0, 0xFF_55_AA_FF));
Style style = Style.width(280).height(160)
.background(sunset)
.borderRadius(8)
.build();Radial spotlight:
Paint glow = Paint.radial(0.5, 0.5, 0.7, 0.7,
Paint.stop(0.0, 0xFF_FF_FF_FF),
Paint.stop(1.0, 0xFF_11_22_44));Conic for color-wheel feel:
Paint wheel = Paint.conic(0,
Paint.stop(0.00, 0xFF_FF_55_55),
Paint.stop(0.25, 0xFF_FF_DD_55),
Paint.stop(0.50, 0xFF_55_FF_88),
Paint.stop(0.75, 0xFF_55_AA_FF),
Paint.stop(1.00, 0xFF_FF_55_55));Style.textFill(Paint) paints text glyphs with the same paint shapes. Each codepoint is drawn individually with the paint sampled at its glyph center, so multi-stop / radial / conic all work uniformly. Style.bold() is preserved on the gradient path — bold routes through MC's standard §l mechanism applied per glyph.
Style title = Style.builder()
.fontSize(24).bold()
.textFill(Paint.linear(0,
Paint.stop(0.0, 0xFF_FF_55_55),
Paint.stop(1.0, 0xFF_55_AA_FF)))
.build();Setting backgroundColor(int) or textColor(int) clears any paint already configured on that channel — last-write-wins. Conversely, calling background(Paint) keeps the legacy getBackgroundColor() getter meaningful by syncing it to the paint's first-stop color, so code that hasn't migrated to getBackgroundPaint() keeps working.
Gradients are rendered with a per-row scanline fill: each row is walked once, color is sampled at each pixel, and adjacent pixels with near-identical (5-bit-quantized) colors are coalesced into a single DrawContext.fill. The output is a few dozen fills per row at most regardless of the rect's width — comparable in cost to the rounded-corner code path. Solid fills bypass the scanline walk entirely and run as cheaply as the original fillRoundRect.
Style.font(Identifier) switches text rendering to a Minecraft resource-pack font. Minecraft natively supports TTF, bitmap, and unihex providers via the resource-pack font system; the library just exposes the identifier so you can apply it from your Style.
import net.minecraft.util.Identifier;
Style title = Style.builder()
.font(Identifier.of("yourmod", "my_font"))
.fontSize(24)
.build();That Identifier resolves to assets/yourmod/font/my_font.json in your resource pack. A typical TTF font definition looks like:
{
"providers": [
{
"type": "ttf",
"file": "yourmod:my_font.ttf",
"shift": [0, 0],
"size": 11.0,
"oversample": 1.0
}
]
}The TTF itself goes at assets/yourmod/font/my_font.ttf. The library does not ship any sample font — you provide the file in your own resource pack.
font(...) is honored by Components.Text. Width measurement re-runs through the styled Text so layout matches what's drawn. Combining font(...) with textFill(Paint.linear(...)) works — bold + custom font + gradient also composes correctly.