public class SurfaceVector
- Object
- SurfaceNode
- SurfaceVector
A retained vector drawing node: a small catalog of fill/stroke/text operations recorded in
paint order and replayed natively by every platform renderer (SwiftUI Canvas on iOS, an
in-process bitmap on Android, Codename One Graphics on desktop). It exists for the widgets
the sealed template catalog cannot express – clocks, gauges, dials and similar custom art –
without shipping pre-rendered images for every state.
Operations use a logical coordinate space (the view box passed to the constructor) that is scaled to the node’s laid-out bounds preserving aspect ratio and centered, so the same op list renders correctly at every widget size.
Angles: the clock convention
All angles in this class are degrees where 0 points up (12 o’clock) and positive angles advance clockwise – the natural convention for clock hands and gauge needles. Renderers convert internally to each platform’s native arc convention.
Rotation groups
Operations added between beginRotation(...) and endRotation() rotate together around a
pivot. The angle is either fixed or read from the entry state map by key, which is what makes
an analog clock cheap: publish the face layout once and drive the hands with per-entry state:
SurfaceVector face = new SurfaceVector(200, 200)
.fillEllipse(100, 100, 96, 96, SurfaceColor.BACKGROUND)
.strokeEllipse(100, 100, 96, 96, 4, SurfaceColor.LABEL)
.beginRotation("hourAngle", 100, 100)
.line(100, 100, 100, 52, 8, SurfaceColor.LABEL)
.endRotation()
.beginRotation("minuteAngle", 100, 100)
.line(100, 100, 100, 24, 5, SurfaceColor.ACCENT)
.endRotation()
.fillEllipse(100, 100, 6, 6, SurfaceColor.ACCENT);
// one timeline entry per minute; the OS flips entries on schedule without waking the app
WidgetTimeline t = new WidgetTimeline().setContent(face);
for (int m = 0; m < 60; m++) {
int totalMinutes = hourOfDay * 60 + minute + m;
Map<String, Object> state = new HashMap<String, Object>();
state.put("minuteAngle", Float.valueOf(totalMinutes % 60 * 6f));
state.put("hourAngle", Float.valueOf(totalMinutes % 720 * 0.5f));
t.addEntry(new Date(startOfMinute + m * 60000L), state);
}
A state-driven angle does not tick by itself – state is per timeline entry, so a clock publishes one entry per minute (as above) and the OS flips them on its own schedule.
Descriptors cap the total operation count at 512 per vector node; exceeding it fails at
serialization time. Unbalanced beginRotation/endRotation pairs also fail at serialization
time with IllegalStateException.
Constructors
public SurfaceVector(int viewBoxWidth, int viewBoxHeight) | Creates a vector node with a logical coordinate space. |
Methods
Inherited methods
Constructor details
SurfaceVector
public SurfaceVector(int viewBoxWidth, int viewBoxHeight)Parameters
viewBoxWidthint- the logical width of the drawing coordinate space
viewBoxHeightint- the logical height of the drawing coordinate space
Method details
fillRect
public SurfaceVector fillRect(float x, float y, float w, float h, SurfaceColor c)Parameters
xfloat- left edge in view-box units
yfloat- top edge in view-box units
wfloat- width in view-box units
hfloat- height in view-box units
cSurfaceColor- the fill color
Returns
fillRoundRect
public SurfaceVector fillRoundRect(float x, float y, float w, float h, float corner, SurfaceColor c)Parameters
xfloat- left edge in view-box units
yfloat- top edge in view-box units
wfloat- width in view-box units
hfloat- height in view-box units
cornerfloat- the corner radius in view-box units
cSurfaceColor- the fill color
Returns
fillEllipse
public SurfaceVector fillEllipse(float cx, float cy, float rx, float ry, SurfaceColor c)Parameters
cxfloat- center x in view-box units
cyfloat- center y in view-box units
rxfloat- horizontal radius in view-box units
ryfloat- vertical radius in view-box units
cSurfaceColor- the fill color
Returns
fillArc
public SurfaceVector fillArc(float cx, float cy, float rx, float ry, float startDeg, float sweepDeg, SurfaceColor c)Parameters
cxfloat- center x in view-box units
cyfloat- center y in view-box units
rxfloat- horizontal radius in view-box units
ryfloat- vertical radius in view-box units
startDegfloat- the start angle in clock degrees
sweepDegfloat- the sweep in degrees, clockwise positive
cSurfaceColor- the fill color
Returns
strokeEllipse
public SurfaceVector strokeEllipse(float cx, float cy, float rx, float ry, float strokeWidth, SurfaceColor c)Parameters
cxfloat- center x in view-box units
cyfloat- center y in view-box units
rxfloat- horizontal radius in view-box units
ryfloat- vertical radius in view-box units
strokeWidthfloat- the stroke width in view-box units
cSurfaceColor- the stroke color
Returns
strokeArc
public SurfaceVector strokeArc(float cx, float cy, float rx, float ry, float startDeg, float sweepDeg, float strokeWidth, SurfaceColor c)Parameters
cxfloat- center x in view-box units
cyfloat- center y in view-box units
rxfloat- horizontal radius in view-box units
ryfloat- vertical radius in view-box units
startDegfloat- the start angle in clock degrees
sweepDegfloat- the sweep in degrees, clockwise positive
strokeWidthfloat- the stroke width in view-box units
cSurfaceColor- the stroke color
Returns
line
public SurfaceVector line(float x1, float y1, float x2, float y2, float strokeWidth, SurfaceColor c)Parameters
x1float- start x in view-box units
y1float- start y in view-box units
x2float- end x in view-box units
y2float- end y in view-box units
strokeWidthfloat- the stroke width in view-box units
cSurfaceColor- the stroke color
Returns
fillPath
public SurfaceVector fillPath(float[] xy, boolean close, SurfaceColor c)close.Parameters
xyfloat[]- coordinate pairs
x0, y0, x1, y1, ...in view-box units, at least three points closeboolean- whether the serialized path is marked closed (kept for renderer symmetry with
strokePath) cSurfaceColor- the fill color
Returns
strokePath
public SurfaceVector strokePath(float[] xy, boolean close, float strokeWidth, SurfaceColor c)Parameters
xyfloat[]- coordinate pairs
x0, y0, x1, y1, ...in view-box units, at least two points closeboolean- whether the last point connects back to the first
strokeWidthfloat- the stroke width in view-box units
cSurfaceColor- the stroke color
Returns
text
public SurfaceVector text(String text, float x, float y, float fontSize, SurfaceFontWeight w, SurfaceColor c)x with its baseline at y. The text supports
${key} interpolation from the entry state map, like SurfaceText.Parameters
textString- the text, may embed
${key}placeholders xfloat- the horizontal anchor (text centers on it) in view-box units
yfloat- the text baseline in view-box units
fontSizefloat- the font size in view-box units
wSurfaceFontWeight- the font weight
cSurfaceColor- the text color
Returns
beginRotation
public SurfaceVector beginRotation(float degrees, float pivotX, float pivotY)endRotation() rotates by degrees (clock convention: clockwise positive) around the
pivot. Groups nest.Parameters
degreesfloat- the rotation in degrees, clockwise positive
pivotXfloat- the pivot x in view-box units
pivotYfloat- the pivot y in view-box units
Returns
beginRotation
public SurfaceVector beginRotation(String degreesStateKey, float pivotX, float pivotY)Number in degrees, clockwise positive. This is how clock hands and gauge needles animate
– a per-entry timeline updates the angle without republishing the layout.Parameters
degreesStateKeyString- the state-map key holding the angle in degrees
pivotXfloat- the pivot x in view-box units
pivotYfloat- the pivot y in view-box units
Returns
endRotation
public SurfaceVector endRotation()Returns
getViewBoxWidth
public int getViewBoxWidth()getViewBoxHeight
public int getViewBoxHeight()getOpCount
public int getOpCount()setPadding
public SurfaceVector setPadding(int all)Parameters
allint- padding in dips
Returns
setPadding
public SurfaceVector setPadding(int top, int right, int bottom, int left)Parameters
topint- top padding in dips
rightint- right padding in dips
bottomint- bottom padding in dips
leftint- left padding in dips
Returns
setBackground
public SurfaceVector setBackground(SurfaceColor background)Parameters
backgroundSurfaceColor- the background color
Returns
setCornerRadius
public SurfaceVector setCornerRadius(int radius)Parameters
radiusint- the corner radius in dips
Returns
setAlignment
public SurfaceVector setAlignment(SurfaceAlignment alignment)SurfaceBox all nine positions apply;
in rows and columns only the cross-axis component is used.Parameters
alignmentSurfaceAlignment- the alignment
Returns
setWeight
public SurfaceVector setWeight(int weight)Parameters
weightint- the relative weight, 0 for natural sizing
Returns
setSize
public SurfaceVector setSize(int widthDips, int heightDips)Parameters
widthDipsint- fixed width in dips, 0 for natural width
heightDipsint- fixed height in dips, 0 for natural height
Returns
setAction
public SurfaceVector setAction(String actionId)Surfaces.setActionHandler(...).
Note that small iOS home-screen widgets only honor the action of the root node.Parameters
actionIdString- the app-defined action identifier
Returns
setAction
public SurfaceVector setAction(String actionId, Map<String, Object> params)String,
Number and Boolean values and is delivered verbatim with the SurfaceActionEvent.Parameters
actionIdString- the app-defined action identifier
paramsMap<String, Object>- parameters delivered with the action, may be null