Expand description
Gradient decoration layers for super::ButtonWidget’s
super::ButtonDecoration seam: a ported GradientButtonDecoration
implementation painting fill/overlay/outline/foreground gradients over (or
instead of) the core’s solid layers.
§Gradient classes ported (from buttons/utils/)
| Reference | Here | Note |
|---|---|---|
m3eGradientFillLayer / m3eGradientBackgroundBuilder (m3e_button_gradient_fill.dart:6/:32) | GradientButtonDecoration::paint_fill | disabled dims to DISABLED_CONTAINER_OPACITY — see below |
m3eGradientForegroundLayer / m3eGradientForegroundBuilder (m3e_button_gradient_foreground.dart:4/:22) | super::ButtonDecoration::foreground_brush | label only, not the icon — see that method’s doc |
m3eGradientOutlineLayer / M3EGradientOutlinePainter / m3eOutlineWidth (m3e_button_gradient_outline.dart:4/:26/:74) | GradientButtonDecoration::paint_outline | strokes ButtonSurface::outline_width regardless of variant, matching upstream’s unconditional apply |
m3eOverlayOpacityFor / m3eStatesForInteraction / m3eGradientOverlayLayer / m3eResolveGradientOverlay / m3eUsesGradientOverlay (m3e_button_gradient_overlay.dart:6/:23/:37/:68/:90) | GradientStates::from_surface + GradientButtonDecoration::paint_overlay | opacity reuses [InteractionState::resolve_opacity], numerically identical to m3eOverlayOpacityFor’s own table |
m3eGradientSurfaceBuilder (m3e_button_gradient_surface.dart:11) | the seam itself: super::ButtonDecoration’s fill→overlay→outline paint order | assembled here as three independent trait methods rather than one nested builder closure, since [super::ButtonWidget::paint] already calls the three in that order |
m3eGradientSpanRect (m3e_button_gradient_span.dart:6) | not ported | maps a button’s local rect into a sibling’s box via GlobalKey/RenderBox.findRenderObject/localToGlobal — super::ButtonSurface carries no cross-widget lookup, and this is ButtonGroup’s shared-gradient-span concern (a future task), not a single button’s |
Flutter’s LinearGradient/RadialGradient/SweepGradient themselves are
stock dart:ui classes, not authored anywhere in material_3_expressive
— GradientSpec ports their createShader position/stop math (see
GradientAlignment::within_rect and implied_stops) since the button
utils above only ever consume a Gradient, never define one.
§PaintScene gradient-support finding: native
peniko::Brush::Gradient flows unmodified through
frust::authoring::PaintScene::fill_rounded_rect_brush/fill_path/
stroke_path/draw_glyph_run into a real
frust_scene::Command carrying the brush,
and the engine’s own compiler encodes it through its gradient LUT
(crates/frust-engine/src/compile/paint.rs’s encode_brush), while the
CPU oracle hands a Brush::Gradient straight to
vello_cpu::PaintType::Gradient (crates/frust-testing/src/oracle_cpu.rs)
— so this module paints real gradients on both rasterizers, not a
banded-solid approximation.
The one gap is frust::authoring::PaintScene::fill_rect_brush (the
unrounded rect variant), whose default falls back to a solid color for a
non-SceneBuilder recorder scene; this module never calls it — every fill
goes through fill_rounded_rect_brush, which the button core already uses
for its own solid container fill.
§Scope narrowed from the reference (both documented, not silent)
- Foreground gradient tints the label, not the icon. See
super::ButtonDecoration::foreground_brush’s doc for why: a gradient brush painted directly on a glyph run is pixel-equivalent to upstream’sShaderMask+BlendMode.srcIn, but the icon is an opaque nestedfrust::authoring::ChildPodthis seam cannot reach into. - No
GradientTransform/focal-point radial/customTileMode. Every gradient in this repo’s ownmaterial_3_expressive(including its playground examples,example/lib/pages/playground/do/buttons_playground.dart:152) uses plainLinearGradient(colors: [...])with implied stops and no transform or focal point —GradientSpecports exactly that surface (colors, explicit stops, begin/end/center/angles) and always resolvespeniko::Extend::Pad(dart:ui’s ownTileMode.clampdefault), rather than speculatively porting knobs nothing in this codebase exercises.
Structs§
- Gradient
Alignment - A normalized
[-1, 1] x [-1, 1]position, ported fromdart:ui’sAlignment— the coordinate space a FlutterLinearGradient’sbegin/endand aRadialGradient/SweepGradient’scenterare expressed in. - Gradient
Button Decoration - A
ButtonDecorationpainting gradient fill/overlay/outline/foreground layers — the reference’sM3EButtonDecorationgradient quadruple (backgroundGradient/overlayGradient/outlineGradient/foregroundGradient,m3e_button_decoration.dart:83-:92) realized against this crate’sButtonDecorationseam. See the module docs for the full gradient-class inventory and scope notes. - Gradient
States - The
Set<WidgetState>snapshot aGradientPropertyresolves against —m3eStatesForInteraction(m3e_button_gradient_overlay.dart:23). - Linear
Gradient Spec - A linear gradient along the line from
begintoend—dart:ui’sLinearGradient. - Radial
Gradient Spec - A radial gradient centered at
center, reachingradius(a fraction of the paint box’s shortest side) —dart:ui’sRadialGradient, minus itsfocal/focalRadiustwo-point knobs (see this module’s Scope Narrowed section). - Sweep
Gradient Spec - A sweep (conic) gradient rotating around
centerfromstart_angletoend_angle, in radians measured clockwise from the positive X-axis (a Y-down coordinate system) —dart:ui’sSweepGradient, and the exact conventionpeniko::SweepGradientPositionitself documents, so no angle-flip is needed at the boundary.
Enums§
- Gradient
Spec - The reference’s
Gradientsealed hierarchy as consumed by a button decoration — one ofLinearGradientSpec/RadialGradientSpec/SweepGradientSpec.
Functions§
- constant_
gradient - A
GradientPropertythat resolves tospecin every state —WidgetStateProperty.all(gradient), the shape every gradient button inmaterial_3_expressive’s own playground uses (example/lib/pages/playground/do/buttons_playground.dart:151). - implied_
stops - Evenly-spaced fallback stops for a gradient whose
stopsis unset —dart:ui’sGradient._impliedStops():ncolors getnstops ati / (n - 1); a single color pins to one stop at0.0; zero colors yields no stops.
Type Aliases§
- Gradient
Property - A per-state gradient resolver — the reference’s
WidgetStateProperty<Gradient?>.