Documentation
¶
Overview ¶
Package zone implements the zone-based layout system for the display.
Package zone manages per-zone plugin configuration. ConfigManager delegates storage to the shared store.DB, reading and writing zones.config_json as the single source of truth for per-zone plugin config (zone_plugin_config was removed in schema migration v5).
Package zone manages display zones, plugin sampling, and page transitions.
Index ¶
- Constants
- Variables
- func ExportConfigToYAML(cfg *Config) ([]byte, error)
- func NormalizePluginID(id string) string
- func RenderDetailFrame(_ *slog.Logger, payload plugin.DetailPayload, theme Theme) *image.RGBA
- func RenderPlaceholder(width, height int, text string, bgColor, fgColor color.RGBA) *image.RGBA
- func SaveConfigToDB(db LayoutImporter, cfg *Config) error
- type Alignment
- type CatalogEntry
- type Compositor
- type Config
- type ConfigManager
- func (m *ConfigManager) BroadcastConfigChange(_ map[string]any)
- func (m *ConfigManager) BroadcastZoneConfigChange(zoneID string, cfg map[string]any) error
- func (m *ConfigManager) DeleteZoneOverride(zoneID string) error
- func (m *ConfigManager) Get(zoneID, _ string) map[string]any
- func (m *ConfigManager) GetZoneOverride(zoneID string) map[string]any
- func (m *ConfigManager) SetZoneOverride(zoneID string, cfg map[string]any) error
- type LayoutImporter
- type Manager
- func (m *Manager) CancelLiveSwipe() error
- func (m *Manager) ClearDetail()
- func (m *Manager) CycleZonePlugin(zoneID string) error
- func (m *Manager) EffectiveTapAction(z ZoneConfig) TapAction
- func (m *Manager) FinalizeLiveSwipe(progress float32, velocity float32, isLeft bool) error
- func (m *Manager) GetConfig() *Config
- func (m *Manager) GetCurrentPage() int
- func (m *Manager) GetDetailFrame() *image.RGBA
- func (m *Manager) GetLastFrame() *image.RGBA
- func (m *Manager) GetPageInfos() []PageInfo
- func (m *Manager) GetZones() map[string]*Zone
- func (m *Manager) HandleDetailTap(x, y int)
- func (m *Manager) HandleZoneTap(zoneID string) error
- func (m *Manager) HandleZoneTapAtX(x int) error
- func (m *Manager) IsShowingDetail() bool
- func (m *Manager) IsTransitioning() bool
- func (m *Manager) NextPage() error
- func (m *Manager) NumPages() int
- func (m *Manager) PrevPage() error
- func (m *Manager) Reload() error
- func (m *Manager) ReloadFromConfig(config *Config) error
- func (m *Manager) RenderFrame() (*image.RGBA, error)
- func (m *Manager) SetBackground(path string) error
- func (m *Manager) SetDetailStateCallback(fn func(active bool))
- func (m *Manager) SetOnPageChange(callback func(pageIndex int) error)
- func (m *Manager) SetOnZoneCycle(callback func(zoneConfig ZoneConfig) error)
- func (m *Manager) SetPluginLookup(pl PluginLookup)
- func (m *Manager) ShowDetail(payload plugin.DetailPayload)
- func (m *Manager) Start() error
- func (m *Manager) StartDetailRefresh(zoneID string, tapper plugin.Tapper, interval time.Duration)
- func (m *Manager) StartTapRipple(tapX int)
- func (m *Manager) Stop() error
- func (m *Manager) SwitchPage(pageIndex int) error
- func (m *Manager) SwitchPageWithTransition(pageIndex int, transitionType TransitionType, direction int) error
- func (m *Manager) UpdateLiveSwipe(progress float32, isLeft bool) error
- func (m *Manager) UpdatePayload(zoneID string, payload plugin.Payload) error
- func (m *Manager) UpdateTheme(theme Theme)
- type NavConfig
- type Page
- type PageInfo
- type PluginLookup
- type Renderer
- type Sampler
- func (s *Sampler) AllZoneStatuses() map[string]ZoneStatus
- func (s *Sampler) BroadcastConfigChange(config map[string]any)
- func (s *Sampler) BroadcastZoneConfigChange(zoneID string, config map[string]any) error
- func (s *Sampler) GetCatalog() []CatalogEntry
- func (s *Sampler) GetPlugin(zoneID string) (plugin.Plugin, bool)
- func (s *Sampler) GetZoneStatus(zoneID string) ZoneStatus
- func (s *Sampler) RestartForPage(pageIndex int) error
- func (s *Sampler) RestartZone(zoneConfig ZoneConfig) error
- func (s *Sampler) Start() error
- func (s *Sampler) Stop()
- type TapAction
- type TapRipple
- type Theme
- type TransitionState
- func (ts *TransitionState) AnimateManualTo(target float64, _ time.Duration)
- func (ts *TransitionState) FinalizeManual(releaseVelocityPxS float32)
- func (ts *TransitionState) GetProgress() float64
- func (ts *TransitionState) IsComplete() bool
- func (ts *TransitionState) IsManual() bool
- func (ts *TransitionState) ManualProgress() float64
- func (ts *TransitionState) Render() *image.RGBA
- func (ts *TransitionState) SetManualProgress(progress float64)
- func (ts *TransitionState) Start(transType TransitionType, oldFrame, newFrame *image.RGBA, direction int)
- func (ts *TransitionState) StartManual(transType TransitionType, oldFrame, newFrame *image.RGBA, direction int)
- type TransitionType
- type Zone
- type ZoneConfig
- type ZoneInfo
- type ZoneStatus
Constants ¶
const ( DisplayWidth = 640 DisplayHeight = 48 )
const ( // MaxZonesPerPage is the maximum number of zones allowed on a single page. MaxZonesPerPage = 6 // DisplayWidthPx is the total pixel width of the Nexus display strip. DisplayWidthPx = 640 // MinZoneWidthPx is the minimum pixel width of any zone. MinZoneWidthPx = 80 )
const ( DetailCloseX = DisplayWidth - 10 DetailCloseY = 10 )
DetailCloseX/Y are the hardware pixel centre of the close (✕) glyph.
Variables ¶
var ( SeverityColorWarn = design.Warn SeverityColorCrit = design.Crit )
Severity display colors — sourced from design tokens; never configurable.
Functions ¶
func ExportConfigToYAML ¶
ExportConfigToYAML serialises cfg to YAML bytes using the struct's yaml tags. The result can be written directly to a .yaml file or returned as an HTTP download.
func NormalizePluginID ¶
normalizePluginID converts legacy path-form exec IDs to the canonical short form.
exec:./plugins/cpu-temp/nexus-cpu-temp → exec:nexus-cpu-temp exec:nexus-cpu-temp → exec:nexus-cpu-temp (unchanged) builtin:clock → builtin:clock (unchanged)
func RenderDetailFrame ¶
RenderDetailFrame blits the pre-rendered pixel buffer from payload.RawFrame onto a 640×48 RGBA image. If RawFrame is absent or the wrong size, a plain error frame is returned so the display always shows something.
func RenderPlaceholder ¶
RenderPlaceholder renders a placeholder zone (for loading or errors).
func SaveConfigToDB ¶
func SaveConfigToDB(db LayoutImporter, cfg *Config) error
SaveConfigToDB persists cfg to the database as a full atomic replace using ImportLayout. Page IDs are assigned sequentially from 1; callers should reload from DB after commit so the manager has the canonical IDs.
Types ¶
type CatalogEntry ¶
type CatalogEntry struct {
ID string `json:"id"` // e.g. "builtin:clock" or "exec:nexus-cpu-temp"
Kind string `json:"kind"` // "builtin" or "exec"
Descriptor plugin.Descriptor `json:"descriptor"`
}
CatalogEntry is one entry in the plugin catalog returned by GetCatalog.
type Compositor ¶
type Compositor struct {
// contains filtered or unexported fields
}
Compositor composites multiple zone renderers into a single display image.
func NewCompositor ¶
func NewCompositor(logger *slog.Logger, theme Theme, page *Page) *Compositor
NewCompositor creates a new compositor for a page.
func (*Compositor) ClearBackground ¶
func (c *Compositor) ClearBackground()
ClearBackground removes the background layer (reverts to solid bg colour).
func (*Compositor) Composite ¶
func (c *Compositor) Composite(dst *image.RGBA, zoneImages map[string]*image.RGBA, theme Theme) (*image.RGBA, error)
Composite renders all zones and composites them into dst. If dst is nil a new 640×48 RGBA image is allocated. Pass a pre-allocated buffer to avoid allocation on the hot path. theme is passed in so live UpdateTheme calls are reflected immediately.
func (*Compositor) SetBackground ¶
func (c *Compositor) SetBackground(img *image.RGBA)
SetBackground sets a static image as the background layer.
func (*Compositor) SetBackgroundGIF ¶
func (c *Compositor) SetBackgroundGIF(g *gif.GIF)
SetBackgroundGIF sets an animated GIF as the background layer. The GIF is decoded into paletted frames and played back at its own frame rate.
type Config ¶
type Config struct {
Name string `yaml:"name" json:"name"` // Layout name
Version string `yaml:"version" json:"version"` // Layout version
Theme Theme `yaml:"theme" json:"theme"` // Global theme
Pages []Page `yaml:"pages" json:"pages"` // Pages (swipeable layouts)
}
Config represents the complete layout configuration
func CopyConfig ¶
CopyConfig returns a deep copy of cfg without JSON round-tripping. Only the two reference types in ZoneConfig need explicit copying:
- PluginConfig map[string]any — shallow map copy (values are JSON scalars)
- ThemeOverride *Theme — copy the pointed-to struct
func LoadConfig ¶
LoadConfig loads a zone configuration from YAML.
func LoadConfigFromDB ¶
LoadConfigFromDB reconstructs a Config from the layout stored in the database. Pages are returned in ord order; zones within each page are returned in ord order.
The global theme is always DefaultTheme() because theme is not persisted per-layout in the DB — per-zone ThemeOverrides are stored in theme_json and are applied to individual zones.
Returns an error (and the caller should fall back to YAML) when the DB contains no pages.
type ConfigManager ¶
type ConfigManager struct {
// contains filtered or unexported fields
}
ConfigManager manages zone-specific plugin configurations. It is a thin adapter between the zone package and the store layer.
func NewConfigManager ¶
func NewConfigManager(s *store.DB, logger *slog.Logger) *ConfigManager
NewConfigManager creates a ConfigManager backed by the given store.
func (*ConfigManager) BroadcastConfigChange ¶
func (m *ConfigManager) BroadcastConfigChange(_ map[string]any)
BroadcastConfigChange is a no-op: global config changes flow through settings.Manager and are delivered to plugins via the sampler.
func (*ConfigManager) BroadcastZoneConfigChange ¶
func (m *ConfigManager) BroadcastZoneConfigChange(zoneID string, cfg map[string]any) error
BroadcastZoneConfigChange persists the config for a single zone.
func (*ConfigManager) DeleteZoneOverride ¶
func (m *ConfigManager) DeleteZoneOverride(zoneID string) error
DeleteZoneOverride clears the plugin config for a zone (resets to {}).
func (*ConfigManager) Get ¶
func (m *ConfigManager) Get(zoneID, _ string) map[string]any
Get returns the plugin config for a zone from zones.config_json. Returns nil when the zone has no stored config or does not exist.
func (*ConfigManager) GetZoneOverride ¶
func (m *ConfigManager) GetZoneOverride(zoneID string) map[string]any
GetZoneOverride returns the stored config for zoneID.
func (*ConfigManager) SetZoneOverride ¶
func (m *ConfigManager) SetZoneOverride(zoneID string, cfg map[string]any) error
SetZoneOverride stores the plugin config for a specific zone.
type LayoutImporter ¶
type LayoutImporter interface {
ImportLayout(pages []store.StoredPage, zonesByPage map[int64][]store.StoredZone) error
}
LayoutImporter can atomically replace the full layout in the database.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager manages zones, their renderers, and lifecycle.
Implementation is split across four files for readability:
manager.go — struct, NewManager, lifecycle (Start/Stop/Reload) manager_page.go — page/config/navigation/cache methods manager_render.go — payload/theme/compositing/frame methods manager_swipe.go — live swipe and transition methods
func NewManager ¶
func NewManager(ctx context.Context, logger *slog.Logger, db *store.DB, fallbackYAMLPath string) (*Manager, error)
NewManager creates a new zone manager.
When db is non-nil the manager loads the layout from SQLite first; if the DB contains no pages it falls back to fallbackYAMLPath and seeds the DB so subsequent starts use the DB path. Pass nil for db (and any string for fallbackYAMLPath) to operate in YAML-only mode (used by the cmd/ binaries).
func (*Manager) CancelLiveSwipe ¶
CancelLiveSwipe cancels an in-progress live swipe and springs back to the current page.
func (*Manager) ClearDetail ¶
func (m *Manager) ClearDetail()
ClearDetail dismisses the detail overlay with a slide-down transition.
func (*Manager) CycleZonePlugin ¶
CycleZonePlugin advances the zone to its next plugin choice and notifies the sampler via the onZoneCycle callback.
func (*Manager) EffectiveTapAction ¶
func (m *Manager) EffectiveTapAction(z ZoneConfig) TapAction
effectiveTapAction returns the tap action for a zone. If the zone's configured on_tap is empty, the plugin's Tapper implementation is the authority: any plugin implementing Tapper gets TapActionDetail automatically. This means on_tap never needs to be set in the layout for detail-capable plugins — the interface is the declaration.
func (*Manager) FinalizeLiveSwipe ¶
FinalizeLiveSwipe commits an in-progress live swipe and smoothly completes the transition using spring physics seeded with the finger's release velocity.
func (*Manager) GetConfig ¶
GetConfig returns the current configuration pointer. The pointer is stable for the duration of the current config — callers must not mutate it.
func (*Manager) GetCurrentPage ¶
GetCurrentPage returns the current page index.
func (*Manager) GetDetailFrame ¶
IsShowingDetail reports whether the detail overlay is active or animating IN. Returns false during the slide-down dismiss transition so taps pass through. GetDetailFrame returns the most recently rendered detail frame, or nil if none. The caller receives a copy safe to read without holding any lock.
func (*Manager) GetLastFrame ¶
GetLastFrame returns a copy of the most recently rendered frame, or nil.
func (*Manager) GetPageInfos ¶
GetPageInfos returns lightweight page + zone descriptors for the Flutter preview UI.
func (*Manager) HandleDetailTap ¶ added in v0.3.0
HandleDetailTap routes a tap within the active detail overlay to the plugin. If the plugin implements DetailTapper, it calls OnDetailTap and dismisses only if the plugin returns false. If the plugin does not implement DetailTapper, the detail is dismissed unconditionally.
func (*Manager) HandleZoneTap ¶
HandleZoneTap looks up the plugin for zoneID, calls OnTap if it implements plugin.Tapper, and shows the result as a detail overlay. Safe to call from any goroutine.
Detail payloads contain pre-rendered pixel frames (RawFrame) with ephemeral content baked in (playback position, live temperatures, etc.). They must always be fetched fresh — caching them produces stale visuals on re-tap. Plugins that need to avoid repeated expensive work (network calls, geocoding) maintain their own in-process cache and return quickly from OnTap.
func (*Manager) HandleZoneTapAtX ¶
HandleZoneTapAtX resolves the zone at hardware X coordinate x (0–639) on the current page and executes its OnTap action — identical to what the hardware touch handler does. Used by the debug tap API so the Flutter preview can drive the same code path with mouse clicks.
func (*Manager) IsShowingDetail ¶
func (*Manager) IsTransitioning ¶
IsTransitioning reports whether a page transition is currently in progress. Used by the render loop to decide whether to broadcast at full rate (30fps).
func (*Manager) Reload ¶
Reload reloads the configuration. When a DB is available it reloads from the database; otherwise it falls back to the YAML file on disk.
func (*Manager) ReloadFromConfig ¶
ReloadFromConfig replaces the running layout with the given config and re-initialises the current page. Used by the layout editor so changes take effect immediately without restarting the application.
func (*Manager) RenderFrame ¶
RenderFrame renders the current frame (transition or live zones composited). When no payload, theme, or page has changed since the last render, it returns the cached lastFrame directly — skipping allocation and the full compositor pipeline. This keeps idle CPU and GC pressure near zero at 30fps.
func (*Manager) SetBackground ¶
SetBackground loads an image or GIF from disk and sets it as the background layer on the current compositor. Passing an empty path clears the background. Supported formats: PNG, JPEG, GIF (animated GIFs play at their own frame rate).
func (*Manager) SetDetailStateCallback ¶
SetDetailStateCallback registers a function called whenever the detail overlay is shown or hidden. Safe to call before Start.
func (*Manager) SetOnPageChange ¶
SetOnPageChange sets a callback to be called when the page changes.
func (*Manager) SetOnZoneCycle ¶
func (m *Manager) SetOnZoneCycle(callback func(zoneConfig ZoneConfig) error)
SetOnZoneCycle sets a callback invoked when a tap action cycles a zone's plugin.
func (*Manager) SetPluginLookup ¶
func (m *Manager) SetPluginLookup(pl PluginLookup)
SetPluginLookup wires in the sampler so HandleZoneTap can resolve plugins.
func (*Manager) ShowDetail ¶
func (m *Manager) ShowDetail(payload plugin.DetailPayload)
ShowDetail renders payload into a detail overlay and starts the slide-up transition.
func (*Manager) StartDetailRefresh ¶ added in v0.3.0
StartDetailRefresh begins polling tapper every interval while the detail overlay is active, updating the frame in place. Call immediately after ShowDetail. A previous refresh goroutine (if any) is cancelled first.
func (*Manager) StartTapRipple ¶ added in v0.2.0
StartTapRipple begins a ripple animation centred on the tapped x coordinate. Safe to call from any goroutine.
func (*Manager) SwitchPage ¶
SwitchPage switches to a different page with a slide-left transition.
func (*Manager) SwitchPageWithTransition ¶
func (m *Manager) SwitchPageWithTransition(pageIndex int, transitionType TransitionType, direction int) error
SwitchPageWithTransition switches to a different page with a specified transition.
func (*Manager) UpdateLiveSwipe ¶
UpdateLiveSwipe updates the live swipe progress for interactive transitions. Called continuously while the user's finger is moving.
func (*Manager) UpdatePayload ¶
UpdatePayload updates the rendered data for a zone and invalidates the page cache.
func (*Manager) UpdateTheme ¶
UpdateTheme applies a new theme to all subsequent rendered frames. Per-zone ThemeOverrides (accent colour, font size, etc.) are re-merged on top of the incoming global theme so they are never stomped by a settings save.
type Page ¶
type Page struct {
Name string `yaml:"name" json:"name"` // Page name
Zones []ZoneConfig `yaml:"zones" json:"zones"` // Zone configurations
}
Page represents a single page of zones
func (*Page) ComputeOffsets ¶
func (p *Page) ComputeOffsets()
ComputeOffsets calculates X offsets for all zones by accumulated width. Always overwrites X — never skip zones with X==0, since the first zone legitimately has X=0 and stale values from a previous layout must not persist.
func (*Page) RedistributeWidths ¶
RedistributeWidths sets every zone's width to an equal share of totalPx, respecting the floorPx minimum. Remainder pixels are distributed one each to the leading zones so the total always equals totalPx exactly. Returns an error if the zones cannot fit within totalPx at floorPx each.
type PluginLookup ¶
PluginLookup is satisfied by Sampler. Manager uses it to resolve a zone's live plugin instance without importing the sampler package directly.
type Renderer ¶
type Renderer struct {
// contains filtered or unexported fields
}
Renderer renders a single zone from a Payload using fogleman/gg.
func NewRenderer ¶
NewRenderer creates a new zone renderer.
func (*Renderer) IsAnimating ¶ added in v0.3.0
IsAnimating returns true if any text slot is actively scrolling or in its end pause. The start pause (showing static ellipsis) does not require continuous re-renders — the frame is static until scrolling begins.
func (*Renderer) UpdateTheme ¶
UpdateTheme replaces the renderer's theme for all subsequent Render calls.
type Sampler ¶
type Sampler struct {
// contains filtered or unexported fields
}
Sampler manages periodic sampling of modules and updating zone payloads
func NewSampler ¶
func NewSampler(ctx context.Context, logger *slog.Logger, manager *Manager, zoneCfg *ConfigManager, pluginsDir string) *Sampler
NewSampler creates a new plugin sampler. pluginsDir is the absolute path to the directory containing exec: plugin binaries. Pass "" to use the default (sibling plugins/ directory next to the running executable).
func (*Sampler) AllZoneStatuses ¶
func (s *Sampler) AllZoneStatuses() map[string]ZoneStatus
AllZoneStatuses returns a snapshot of all zone statuses.
func (*Sampler) BroadcastConfigChange ¶
BroadcastConfigChange delivers a global config update to all loaded plugins. Kept for the settings-level config path; zone-specific config goes through BroadcastZoneConfigChange.
func (*Sampler) BroadcastZoneConfigChange ¶
BroadcastZoneConfigChange delivers a config update to a specific zone's plugin.
func (*Sampler) GetCatalog ¶
func (s *Sampler) GetCatalog() []CatalogEntry
GetCatalog returns metadata for all available plugins: running builtins (from the loaded modules map) plus every executable found in pluginsDir. Exec plugins not currently loaded are launched briefly to retrieve their Descriptor.
func (*Sampler) GetPlugin ¶
GetPlugin returns the live plugin instance for zoneID, if one is loaded.
func (*Sampler) GetZoneStatus ¶
func (s *Sampler) GetZoneStatus(zoneID string) ZoneStatus
ZoneStatus returns the last known health status for a zone. Returns {Status: "loading"} if no sample has completed yet.
func (*Sampler) RestartForPage ¶
RestartForPage restarts sampling for a new page. Old zone goroutines are cancelled and new ones start immediately — we don't wait for old goroutines to exit so there's no blocking delay.
func (*Sampler) RestartZone ¶
func (s *Sampler) RestartZone(zoneConfig ZoneConfig) error
RestartZone stops and restarts sampling for a single zone with a new plugin spec. Used when a tap action cycles the zone to its next plugin choice.
type TapRipple ¶ added in v0.2.0
type TapRipple struct {
// contains filtered or unexported fields
}
TapRipple tracks a single in-flight tap ripple animation.
type Theme ¶
type Theme struct {
Bg string `yaml:"bg" json:"bg"` // Background color (hex)
Fg string `yaml:"fg" json:"fg"` // Foreground color (hex)
Muted string `yaml:"muted" json:"muted"` // Muted text color (hex)
Accent string `yaml:"accent" json:"accent"` // Accent color (hex)
ZoneBg string `yaml:"zone_bg,omitempty" json:"zone_bg,omitempty"` // Zone background color (hex)
GutterPx int `yaml:"gutter_px,omitempty" json:"gutter_px,omitempty"` // Gutter width
FontSizePrimary int `yaml:"font_size_primary,omitempty" json:"font_size_primary,omitempty"` // Primary text size
FontSizeSecondary int `yaml:"font_size_secondary,omitempty" json:"font_size_secondary,omitempty"` // Secondary text size
GraphBgOpacity int `yaml:"graph_bg_opacity,omitempty" json:"graph_bg_opacity,omitempty"` // Graph background opacity (0-100)
GraphLineOpacity int `yaml:"graph_line_opacity,omitempty" json:"graph_line_opacity,omitempty"` // Graph line opacity (0-100)
}
Theme represents visual styling
func (*Theme) GetAccentColor ¶
GetAccentColor returns the accent color as color.RGBA
func (*Theme) GetBgColor ¶
GetBgColor returns the background color as color.RGBA
func (*Theme) GetFgColor ¶
GetFgColor returns the foreground color as color.RGBA
func (*Theme) GetMutedColor ¶
GetMutedColor returns the muted color as color.RGBA
func (*Theme) GetZoneBgColor ¶
GetZoneBgColor returns the zone background color as color.RGBA
type TransitionState ¶
type TransitionState struct {
Active bool
Type TransitionType
StartTime time.Time
Duration time.Duration
OldFrame *image.RGBA // Previous page frame
NewFrame *image.RGBA // New page frame
Direction int // 1 for forward, -1 for backward
// contains filtered or unexported fields
}
TransitionState tracks the current state of a page transition.
func NewTransitionState ¶
func NewTransitionState() *TransitionState
NewTransitionState creates a new transition state.
func (*TransitionState) AnimateManualTo ¶
func (ts *TransitionState) AnimateManualTo(target float64, _ time.Duration)
AnimateManualTo starts a spring snap toward target (0 = cancel, 1 = commit) with zero initial velocity. Used for cancel snaps where we don't have a meaningful release velocity.
func (*TransitionState) FinalizeManual ¶
func (ts *TransitionState) FinalizeManual(releaseVelocityPxS float32)
FinalizeManual starts a spring snap toward 1 (commit), seeded with the finger's release velocity converted to progress-units/second. releaseVelocityPxS is the finger speed in pixels/second from the touch reader.
func (*TransitionState) GetProgress ¶
func (ts *TransitionState) GetProgress() float64
GetProgress returns the transition progress (0.0 to 1.0) and advances the spring simulation if active.
func (*TransitionState) IsComplete ¶
func (ts *TransitionState) IsComplete() bool
IsComplete returns whether the transition is finished.
func (*TransitionState) IsManual ¶
func (ts *TransitionState) IsManual() bool
IsManual returns true if the transition is currently under manual control.
func (*TransitionState) ManualProgress ¶
func (ts *TransitionState) ManualProgress() float64
ManualProgress returns the current manual progress (0-1).
func (*TransitionState) Render ¶
func (ts *TransitionState) Render() *image.RGBA
Render renders the current transition frame.
func (*TransitionState) SetManualProgress ¶
func (ts *TransitionState) SetManualProgress(progress float64)
SetManualProgress updates the progress for a finger-driven transition.
func (*TransitionState) Start ¶
func (ts *TransitionState) Start(transType TransitionType, oldFrame, newFrame *image.RGBA, direction int)
Start begins a transition from oldFrame to newFrame.
func (*TransitionState) StartManual ¶
func (ts *TransitionState) StartManual(transType TransitionType, oldFrame, newFrame *image.RGBA, direction int)
StartManual begins a transition driven by explicit progress updates.
type TransitionType ¶
type TransitionType int
TransitionType defines the type of page transition effect.
const ( TransitionNone TransitionType = iota TransitionFade TransitionSlideLeft TransitionSlideRight TransitionSlideUp TransitionSlideDown )
type Zone ¶
type Zone struct {
Config ZoneConfig
Renderer *Renderer
Plugin string
// contains filtered or unexported fields
}
Zone represents a single zone instance.
type ZoneConfig ¶
type ZoneConfig struct {
ID string `yaml:"id" json:"id"` // Unique zone identifier
Width int `yaml:"width" json:"width"` // Zone width in pixels
X int `yaml:"x,omitempty" json:"x,omitempty"` // X offset (auto-computed if 0)
Plugin string `yaml:"plugin" json:"plugin"` // Plugin endpoint (builtin:name or exec:path)
RefreshMs int `yaml:"refresh_ms" json:"refresh_ms"` // Sampling interval
Align Alignment `yaml:"align,omitempty" json:"align,omitempty"` // Text alignment
ThemeOverride *Theme `yaml:"theme_override,omitempty" json:"theme_override,omitempty"` // Per-zone theme
PluginConfig map[string]any `yaml:"plugin_config,omitempty" json:"plugin_config,omitempty"` // Per-zone plugin configuration
Choices []string `yaml:"choices,omitempty" json:"choices,omitempty"` // Plugin choices for cycling
OnTap TapAction `yaml:"on_tap,omitempty" json:"on_tap,omitempty"` // Tap action
}
ZoneConfig represents configuration for a single zone
func (*ZoneConfig) Validate ¶
func (z *ZoneConfig) Validate() error
Validate checks if a zone configuration is valid
type ZoneInfo ¶
type ZoneInfo struct {
ID string `json:"id"`
Width int `json:"width"`
OnTap string `json:"on_tap,omitempty"`
}
ZoneInfo is a lightweight zone descriptor sent to the Flutter preview UI.
type ZoneStatus ¶
type ZoneStatus struct {
Status string // "ok" | "error" | "timeout" | "loading"
Error string // non-empty when Status is "error" or "timeout"
}
ZoneStatus represents the current health of a single zone's plugin.