theme colors

actual-tui-plugins
Sebastian Herrlinger 2026-03-05 17:15:25 +01:00
parent 91b7d5d4ec
commit 372eba31e8
1 changed files with 74 additions and 8 deletions

View File

@ -68,30 +68,53 @@ const tone = (api: TuiApi) => {
}
type Skin = ReturnType<typeof tone>
type CubeOpts = ConstructorParameters<typeof ThreeRenderable>[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<typeof ThreeRenderable>[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<typeof cfg>) => ({
</box>
)
},
sidebar_top(_ctx, value) {
return <smoke_cube id={`smoke-cube-${value.session_id.slice(0, 8)}`} width="100%" height={16} />
sidebar_top(ctx, value) {
const map = ctx.theme.current as Record<string, unknown>
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 (
<smoke_cube
id={`smoke-cube-${value.session_id.slice(0, 8)}`}
width="100%"
height={16}
tint={get("primary", ui.accent)}
spec={get("text", ui.text)}
ambient={get("textMuted", ui.muted)}
key_light={get("success", ui.accent)}
fill_light={get("info", ui.accent)}
/>
)
},
},
})