Class SurfaceVector

java.lang.Object
com.codename1.surfaces.SurfaceNode
com.codename1.surfaces.SurfaceVector

public class SurfaceVector extends SurfaceNode

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.

  • Constructor Details

    • SurfaceVector

      public SurfaceVector(int viewBoxWidth, int viewBoxHeight)

      Creates a vector node with a logical coordinate space. The view box is scaled to the node's laid-out bounds preserving aspect ratio (centered); it also provides the node's natural size in dips when no fixed size or weight applies.

      Parameters
      • viewBoxWidth: the logical width of the drawing coordinate space
      • viewBoxHeight: the logical height of the drawing coordinate space
  • Method Details

    • fillRect

      public SurfaceVector fillRect(float x, float y, float w, float h, SurfaceColor c)

      Fills an axis-aligned rectangle.

      Parameters
      • x: left edge in view-box units
      • y: top edge in view-box units
      • w: width in view-box units
      • h: height in view-box units
      • c: the fill color
      Returns

      this vector node, for chaining

    • fillRoundRect

      public SurfaceVector fillRoundRect(float x, float y, float w, float h, float corner, SurfaceColor c)

      Fills a rectangle with rounded corners.

      Parameters
      • x: left edge in view-box units
      • y: top edge in view-box units
      • w: width in view-box units
      • h: height in view-box units
      • corner: the corner radius in view-box units
      • c: the fill color
      Returns

      this vector node, for chaining

    • fillEllipse

      public SurfaceVector fillEllipse(float cx, float cy, float rx, float ry, SurfaceColor c)

      Fills an ellipse.

      Parameters
      • cx: center x in view-box units
      • cy: center y in view-box units
      • rx: horizontal radius in view-box units
      • ry: vertical radius in view-box units
      • c: the fill color
      Returns

      this vector node, for chaining

    • fillArc

      public SurfaceVector fillArc(float cx, float cy, float rx, float ry, float startDeg, float sweepDeg, SurfaceColor c)

      Fills a pie slice: the elliptical arc between the two angles joined to the center. Angles use the clock convention (degrees, 0 = 12 o'clock, clockwise positive).

      Parameters
      • cx: center x in view-box units
      • cy: center y in view-box units
      • rx: horizontal radius in view-box units
      • ry: vertical radius in view-box units
      • startDeg: the start angle in clock degrees
      • sweepDeg: the sweep in degrees, clockwise positive
      • c: the fill color
      Returns

      this vector node, for chaining

    • strokeEllipse

      public SurfaceVector strokeEllipse(float cx, float cy, float rx, float ry, float strokeWidth, SurfaceColor c)

      Strokes the outline of an ellipse.

      Parameters
      • cx: center x in view-box units
      • cy: center y in view-box units
      • rx: horizontal radius in view-box units
      • ry: vertical radius in view-box units
      • strokeWidth: the stroke width in view-box units
      • c: the stroke color
      Returns

      this vector node, for chaining

    • strokeArc

      public SurfaceVector strokeArc(float cx, float cy, float rx, float ry, float startDeg, float sweepDeg, float strokeWidth, SurfaceColor c)

      Strokes an open elliptical arc with round caps -- the primitive for gauge tracks and progress rings. Angles use the clock convention (degrees, 0 = 12 o'clock, clockwise positive).

      Parameters
      • cx: center x in view-box units
      • cy: center y in view-box units
      • rx: horizontal radius in view-box units
      • ry: vertical radius in view-box units
      • startDeg: the start angle in clock degrees
      • sweepDeg: the sweep in degrees, clockwise positive
      • strokeWidth: the stroke width in view-box units
      • c: the stroke color
      Returns

      this vector node, for chaining

    • line

      public SurfaceVector line(float x1, float y1, float x2, float y2, float strokeWidth, SurfaceColor c)

      Draws a line with round caps.

      Parameters
      • x1: start x in view-box units
      • y1: start y in view-box units
      • x2: end x in view-box units
      • y2: end y in view-box units
      • strokeWidth: the stroke width in view-box units
      • c: the stroke color
      Returns

      this vector node, for chaining

    • fillPath

      public SurfaceVector fillPath(float[] xy, boolean close, SurfaceColor c)

      Fills a polygon built from x,y coordinate pairs. The path is implicitly closed for filling regardless of close.

      Parameters
      • xy: coordinate pairs x0, y0, x1, y1, ... in view-box units, at least three points
      • close: whether the serialized path is marked closed (kept for renderer symmetry with strokePath)
      • c: the fill color
      Returns

      this vector node, for chaining

    • strokePath

      public SurfaceVector strokePath(float[] xy, boolean close, float strokeWidth, SurfaceColor c)

      Strokes a poly-line built from x,y coordinate pairs, with round caps and joins.

      Parameters
      • xy: coordinate pairs x0, y0, x1, y1, ... in view-box units, at least two points
      • close: whether the last point connects back to the first
      • strokeWidth: the stroke width in view-box units
      • c: the stroke color
      Returns

      this vector node, for chaining

    • text

      public SurfaceVector text(String text, float x, float y, float fontSize, SurfaceFontWeight w, SurfaceColor c)

      Draws text anchored at the middle of x with its baseline at y. The text supports ${key} interpolation from the entry state map, like SurfaceText.

      Parameters
      • text: the text, may embed ${key} placeholders
      • x: the horizontal anchor (text centers on it) in view-box units
      • y: the text baseline in view-box units
      • fontSize: the font size in view-box units
      • w: the font weight
      • c: the text color
      Returns

      this vector node, for chaining

    • beginRotation

      public SurfaceVector beginRotation(float degrees, float pivotX, float pivotY)

      Opens a rotation group with a fixed angle: every op added until the matching endRotation() rotates by degrees (clock convention: clockwise positive) around the pivot. Groups nest.

      Parameters
      • degrees: the rotation in degrees, clockwise positive
      • pivotX: the pivot x in view-box units
      • pivotY: the pivot y in view-box units
      Returns

      this vector node, for chaining

    • beginRotation

      public SurfaceVector beginRotation(String degreesStateKey, float pivotX, float pivotY)

      Opens a rotation group whose angle is read from the entry state map: the state value is a 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
      • degreesStateKey: the state-map key holding the angle in degrees
      • pivotX: the pivot x in view-box units
      • pivotY: the pivot y in view-box units
      Returns

      this vector node, for chaining

    • endRotation

      public SurfaceVector endRotation()

      Closes the most recently opened rotation group.

      Returns

      this vector node, for chaining

    • getViewBoxWidth

      public int getViewBoxWidth()
      Returns the logical view-box width.
    • getViewBoxHeight

      public int getViewBoxHeight()
      Returns the logical view-box height.
    • getOpCount

      public int getOpCount()
      Returns the number of recorded operations, rotation groups included.
    • setPadding

      public SurfaceVector setPadding(int all)
      Description copied from class: SurfaceNode

      Sets the same padding on all four sides.

      Parameters
      • all: padding in dips
      Returns

      this node, for chaining

      Overrides:
      setPadding in class SurfaceNode
    • setPadding

      public SurfaceVector setPadding(int top, int right, int bottom, int left)
      Description copied from class: SurfaceNode

      Sets the padding of each side individually.

      Parameters
      • top: top padding in dips
      • right: right padding in dips
      • bottom: bottom padding in dips
      • left: left padding in dips
      Returns

      this node, for chaining

      Overrides:
      setPadding in class SurfaceNode
    • setBackground

      public SurfaceVector setBackground(SurfaceColor background)
      Description copied from class: SurfaceNode

      Sets the background color of this node.

      Parameters
      • color: the background color
      Returns

      this node, for chaining

      Overrides:
      setBackground in class SurfaceNode
    • setCornerRadius

      public SurfaceVector setCornerRadius(int radius)
      Description copied from class: SurfaceNode

      Sets the corner radius applied to the node's background. May render square on Android versions below 12.

      Parameters
      • radius: the corner radius in dips
      Returns

      this node, for chaining

      Overrides:
      setCornerRadius in class SurfaceNode
    • setAlignment

      public SurfaceVector setAlignment(SurfaceAlignment alignment)
      Description copied from class: SurfaceNode

      Sets this node's alignment within its parent. In a SurfaceBox all nine positions apply; in rows and columns only the cross-axis component is used.

      Parameters
      • alignment: the alignment
      Returns

      this node, for chaining

      Overrides:
      setAlignment in class SurfaceNode
    • setWeight

      public SurfaceVector setWeight(int weight)
      Description copied from class: SurfaceNode

      Sets the flexible-space weight of this node within a row or column. Nodes with a weight share the leftover space of the parent proportionally; a weight of 0 (the default) sizes the node to its natural size.

      Parameters
      • weight: the relative weight, 0 for natural sizing
      Returns

      this node, for chaining

      Overrides:
      setWeight in class SurfaceNode
    • setSize

      public SurfaceVector setSize(int widthDips, int heightDips)
      Description copied from class: SurfaceNode

      Sets a fixed size for this node. A value of 0 (the default) keeps the natural size of the respective axis.

      Parameters
      • widthDips: fixed width in dips, 0 for natural width
      • heightDips: fixed height in dips, 0 for natural height
      Returns

      this node, for chaining

      Overrides:
      setSize in class SurfaceNode
    • setAction

      public SurfaceVector setAction(String actionId)
      Description copied from class: SurfaceNode

      Assigns a tap action to this node. Tapping the node opens (or foregrounds) the app and delivers the action id to the handler registered with Surfaces.setActionHandler(...). Note that small iOS home-screen widgets only honor the action of the root node.

      Parameters
      • actionId: the app-defined action identifier
      Returns

      this node, for chaining

      Overrides:
      setAction in class SurfaceNode
    • setAction

      public SurfaceVector setAction(String actionId, Map<String,Object> params)
      Description copied from class: SurfaceNode

      Assigns a tap action with parameters to this node. The parameter map may contain String, Number and Boolean values and is delivered verbatim with the SurfaceActionEvent.

      Parameters
      • actionId: the app-defined action identifier
      • params: parameters delivered with the action, may be null
      Returns

      this node, for chaining

      Overrides:
      setAction in class SurfaceNode