package ui import ( "fmt" "silverpose/v2/internal/fall" "silverpose/v2/internal/source" ) // WindowSpec locks the visual baseline tested by the Windows UI Spike. The // production V2 app will consume the same semantic colours and medium desktop // layout after the decoding/inference pipeline is complete. type WindowSpec struct { Title string Width int Height int BackgroundHex string SurfaceHex string AccentHex string AlertHex string } func MonitorWindowSpec() WindowSpec { return WindowSpec{ Title: "Silver Pose V2", Width: 1120, Height: 720, BackgroundHex: "#EAF1F8", SurfaceHex: "#FFFFFF", AccentHex: "#2563EB", AlertHex: "#C62828", } } // ViewModel is a UI-thread-neutral snapshot. It deliberately stores only a // source environment variable name and status, never a resolved RTSP URL. type ViewModel struct { ConnectionText string StateText string EventText string SettingsSummary string Critical bool } func NewViewModel() ViewModel { return ViewModel{ ConnectionText: "等待启动监控", StateText: "检测状态:正常", EventText: "事件:暂无", } } func (model *ViewModel) Apply(state fall.State, status source.Status) { model.Critical = state == fall.Confirmed switch state { case fall.Confirmed: model.StateText = "检测状态:确认摔倒" model.EventText = "事件:已确认,已保存证据" case fall.Suspect: model.StateText = "检测状态:疑似倒地" model.EventText = "事件:正在持续确认" case fall.Recovering: model.StateText = "检测状态:恢复观察中" model.EventText = "事件:等待恢复稳定" default: model.StateText = "检测状态:正常" model.EventText = "事件:暂无" } switch status { case source.Connected: model.ConnectionText = "视频流:在线" case source.Retrying: model.ConnectionText = "视频流:正在重连,不触发摔倒报警" case source.Stopped: model.ConnectionText = "视频流:已停止" default: model.ConnectionText = "视频流:正在连接" } } func (model *ViewModel) SetSourceReady(environmentName string, ready bool) { state := "未就绪" if ready { state = "已就绪" } model.SettingsSummary = fmt.Sprintf("来源环境变量 %s:%s", environmentName, state) }