diff --git a/.opencode/plugins/tui-smoke.tsx b/.opencode/plugins/tui-smoke.tsx index 2fa8a5e349..7df8dd2869 100644 --- a/.opencode/plugins/tui-smoke.tsx +++ b/.opencode/plugins/tui-smoke.tsx @@ -68,30 +68,53 @@ const tone = (api: TuiApi) => { } type Skin = ReturnType +type CubeOpts = ConstructorParameters[1] & { + tint?: Color + spec?: Color + ambient?: Color + key_light?: Color + fill_light?: Color +} + +const rgb = (value: unknown, fallback: string) => { + if (typeof value === "string") return new THREE.Color(value) + if (value && typeof value === "object") { + const item = value as { r?: unknown; g?: unknown; b?: unknown } + if (typeof item.r === "number" && typeof item.g === "number" && typeof item.b === "number") { + return new THREE.Color(item.r, item.g, item.b) + } + } + return new THREE.Color(fallback) +} class Cube extends ThreeRenderable { private cube: THREE.Mesh + private mat: THREE.MeshPhongMaterial + private amb: THREE.AmbientLight + private key: THREE.DirectionalLight + private fill: THREE.DirectionalLight - constructor(ctx: RenderContext, opts: ConstructorParameters[1]) { + constructor(ctx: RenderContext, opts: CubeOpts) { const scene = new THREE.Scene() const camera = new THREE.PerspectiveCamera(40, 1, 0.1, 100) camera.position.set(0, 0, 2.55) - scene.add(new THREE.AmbientLight(new THREE.Color(0.4, 0.4, 0.4), 1.0)) + const amb = new THREE.AmbientLight(rgb(opts.ambient, "#666666"), 1.0) + scene.add(amb) - const key = new THREE.DirectionalLight(new THREE.Color(1.0, 0.95, 0.9), 1.2) + const key = new THREE.DirectionalLight(rgb(opts.key_light, "#fff2e6"), 1.2) key.position.set(2.5, 2.0, 3.0) scene.add(key) - const fill = new THREE.DirectionalLight(new THREE.Color(0.5, 0.7, 1.0), 0.6) + const fill = new THREE.DirectionalLight(rgb(opts.fill_light, "#80b3ff"), 0.6) fill.position.set(-2.0, -1.5, 2.5) scene.add(fill) const geo = new THREE.BoxGeometry(1.0, 1.0, 1.0) const mat = new THREE.MeshPhongMaterial({ - color: new THREE.Color(0.25, 0.8, 1.0), + color: rgb(opts.tint, "#40ccff"), shininess: 80, - specular: new THREE.Color(0.9, 0.9, 1.0), + specular: rgb(opts.spec, "#e6e6ff"), }) const cube = new THREE.Mesh(geo, mat) cube.scale.setScalar(1.12) @@ -109,6 +132,30 @@ class Cube extends ThreeRenderable { }) this.cube = cube + this.mat = mat + this.amb = amb + this.key = key + this.fill = fill + } + + set tint(value: Color | undefined) { + this.mat.color.copy(rgb(value, "#40ccff")) + } + + set spec(value: Color | undefined) { + this.mat.specular.copy(rgb(value, "#e6e6ff")) + } + + set ambient(value: Color | undefined) { + this.amb.color.copy(rgb(value, "#666666")) + } + + set key_light(value: Color | undefined) { + this.key.color.copy(rgb(value, "#fff2e6")) + } + + set fill_light(value: Color | undefined) { + this.fill.color.copy(rgb(value, "#80b3ff")) } protected override renderSelf(buf: OptimizedBuffer, dt: number): void { @@ -554,8 +601,27 @@ const slot = (input: ReturnType) => ({ ) }, - sidebar_top(_ctx, value) { - return + sidebar_top(ctx, value) { + const map = ctx.theme.current as Record + const get = (name: string, fallback: string) => { + const item = map[name] + if (typeof item === "string") return item + if (item && typeof item === "object") return item as RGBA + return fallback + } + + return ( + + ) }, }, })