Makepad Code (editor layout, selection, sidebar, early yield), the EN/ZH Translator with voice, Weather with a generated offline forecast, Amp playing its offline library, and fixes across the other apps and examples. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
515 lines
26 KiB
Text
515 lines
26 KiB
Text
// title: Hologram
|
|
// Hologram — a Tron console: near-black glass slabs traced by thin cyan-white
|
|
// light lines, keys of translucent glass lit from inside, a faint projected
|
|
// grid and holographic interference over everything, and every part
|
|
// self-luminous so the screen's light and the device's own glow blend.
|
|
use mod.prelude.widgets_internal.*
|
|
|
|
// ---- palette: cyan light on black glass ----
|
|
mod.widgets.hw_palette.screen_bg = #x010508
|
|
mod.widgets.hw_palette.screen_text = #xd9fbff
|
|
mod.widgets.hw_palette.screen_muted = #x5fb3c4
|
|
mod.widgets.hw_palette.accent = #x38e8ff
|
|
mod.widgets.hw_palette.panel_text = #xc8f7ff
|
|
mod.widgets.hw_palette.panel_muted = #x4f9fb0
|
|
mod.widgets.hw_palette.menu_bg = #x03101a
|
|
mod.widgets.hw_palette.spill_color = #x46dcff
|
|
mod.widgets.hw_palette.spill_mono = 0.12
|
|
mod.widgets.hw_palette.spill_knee = 2.0
|
|
mod.widgets.hw_palette.caption_bg = #x010306
|
|
mod.widgets.hw_palette.caption_text = #x7fefff
|
|
|
|
// ---- the front: black glass over a projected grid ----
|
|
mod.widgets.HwChassis.draw_bg.ground = #x02050a
|
|
mod.widgets.HwChassis.draw_bg.light_ink = vec4(0.70, 0.95, 1.0, 1.0)
|
|
mod.widgets.HwChassis.draw_bg.shadow_ink = vec4(0.0, 0.0, 0.0, 1.0)
|
|
mod.widgets.HwChassis.draw_bg.glow_ink = vec4(0.25, 0.90, 1.0, 1.0)
|
|
mod.widgets.HwChassis.draw_bg.spill = vec2(2.4, 0.7)
|
|
mod.widgets.HwChassis.draw_bg.vignette = vec4(0.5, 0.45, 0.30, 1.25)
|
|
mod.widgets.Window.pass.clear_color = #x02050a
|
|
mod.widgets.HwChassis.draw_bg.surface = fn(p: vec2, base: vec3) -> vec3 {
|
|
let w = self.world.xy
|
|
// Minor grid every 24 pt, major every 96, a dot at each major crossing.
|
|
let g1 = abs(fract(w / 24.0 + vec2(0.5, 0.5)) - vec2(0.5, 0.5)) * 24.0
|
|
let g2 = abs(fract(w / 96.0 + vec2(0.5, 0.5)) - vec2(0.5, 0.5)) * 96.0
|
|
let minor = 1.0 - smoothstep(0.2, 0.9, min(g1.x, g1.y))
|
|
let major = 1.0 - smoothstep(0.3, 1.1, min(g2.x, g2.y))
|
|
let node = 1.0 - smoothstep(1.0, 2.2, length(g2))
|
|
// Interference: two nearly equal ripples beat into slow bands.
|
|
let i = sin(dot(w, vec2(0.60, 0.80)) * 0.90) * sin(dot(w, vec2(0.62, 0.785)) * 0.905)
|
|
let band = 0.5 + 0.5 * sin(dot(w, vec2(0.004, 0.011)) + self.hw_noise(w * 0.004) * 4.0)
|
|
var col = base
|
|
col = col + vec3(0.05, 0.28, 0.36) * (minor * 0.10 + major * 0.22 + node * 0.55)
|
|
col = col + mix(vec3(0.0, 0.03, 0.05), vec3(0.03, 0.0, 0.05), band) * (0.4 + 0.3 * i)
|
|
return col
|
|
}
|
|
|
|
// Raised plates: black glass slabs, a light line traced round each edge.
|
|
mod.widgets.HwPlate.radius = 6
|
|
mod.widgets.HwPlate.draw_bg.ground = #x050b12
|
|
mod.widgets.HwPlate.draw_bg.light_ink = vec4(0.30, 0.78, 0.95, 1.0)
|
|
mod.widgets.HwPlate.draw_bg.shadow_ink = vec4(0.0, 0.0, 0.0, 1.0)
|
|
mod.widgets.HwPlate.draw_bg.relief = vec4(1.5, 0.3, 2.5, 0.55)
|
|
mod.widgets.HwPlate.draw_bg.finish = vec4(0.5, 0.30, 0.10, 0.10)
|
|
mod.widgets.HwPlate.draw_bg.tune = vec4(0.06, 0.0, 1.10, 3.0)
|
|
mod.widgets.HwPlate.draw_bg.shadow = vec4(0.85, 12.0, 1.0, 0.6)
|
|
mod.widgets.HwPlate.draw_bg.glow_ink = vec4(0.25, 0.90, 1.0, 1.0)
|
|
mod.widgets.HwPlate.draw_bg.spill = vec2(2.0, 0.5)
|
|
mod.widgets.HwPlate.draw_bg.edge_ink = vec4(0.35, 0.92, 1.0, 1.0)
|
|
mod.widgets.HwPlate.draw_bg.surface = fn(p: vec2, base: vec3) -> vec3 {
|
|
let w = self.world.xy
|
|
let uv = p / max(self.rect_size, vec2(1.0, 1.0))
|
|
var col = base * (1.10 - uv.y * 0.30)
|
|
let scan = 0.5 + 0.5 * sin(w.y * 1.5708)
|
|
col = col + vec3(0.0, 0.035, 0.05) * scan * 0.5
|
|
let t = uv.x * 0.8 + uv.y * 0.35
|
|
let sheet = exp(-(t - 0.35) * (t - 0.35) * 30.0)
|
|
col = col + vec3(0.06, 0.12, 0.16) * sheet * 0.35
|
|
// Holographic foil: slow interference fringes shifting cyan to violet.
|
|
let f = dot(w, vec2(0.018, 0.031)) + self.hw_noise(w * 0.008) * 3.0
|
|
let irid = vec3(0.5 + 0.5 * sin(f * 2.0 + 3.6), 0.5 + 0.5 * sin(f * 2.0 + 1.2), 0.5 + 0.5 * sin(f * 2.0))
|
|
col = col + irid * vec3(0.020, 0.030, 0.045) * (0.5 + 0.5 * sheet)
|
|
// A diffraction grating of fine dots.
|
|
let g = abs(fract(w / 3.0) - vec2(0.5, 0.5)) * 3.0
|
|
col = col + vec3(0.0, 0.03, 0.04) * (1.0 - smoothstep(0.2, 0.7, length(g))) * 0.6
|
|
return col
|
|
}
|
|
mod.widgets.HwPlate.draw_bg.pixel = fn() {
|
|
let p = self.pos * self.rect_size
|
|
var o = self.layer(self.surface(p, self.ground.xyz))
|
|
let px = 1.0 / max(self.draw_pass.dpi_factor, 0.5)
|
|
let d = self.sd(p) + 0.9
|
|
let qe = min(min(p.x, p.y), min(self.rect_size.x - p.x, self.rect_size.y - p.y))
|
|
let fade = smoothstep(0.0, max(self.inset, 1.0), qe)
|
|
let c = self.rect_size * 0.5
|
|
let h = c - vec2(self.inset, self.inset)
|
|
let k = abs(p - c) - h + vec2(26.0, 26.0)
|
|
let corner = smoothstep(0.0, 2.0, k.x) * smoothstep(0.0, 2.0, k.y)
|
|
let bright = 0.45 + 0.55 * corner
|
|
let line = (1.0 - smoothstep(0.3, 0.3 + px * 1.5, abs(d))) * bright
|
|
let halo = exp(-abs(d) / 3.0) * 0.30 * bright * fade
|
|
let inner = exp(min(d, 0.0) / 10.0) * step(d, 0.0) * 0.08
|
|
let ink = self.edge_ink.xyz * self.edge_ink.w
|
|
let core = mix(ink, vec3(1.0, 1.0, 1.0), 0.5 * corner)
|
|
// A holographic fringe: a faint violet ghost of the line just outside it.
|
|
let ghost = (1.0 - smoothstep(0.3, 0.3 + px * 2.0, abs(d - 1.8))) * 0.22 * bright * fade
|
|
return vec4(o.xyz + core * line + ink * (halo + inner) + vec3(0.40, 0.30, 1.0) * ghost, o.w)
|
|
}
|
|
|
|
// Recessed panels: deeper black glass, a dimmer line.
|
|
mod.widgets.HwPanel.radius = 6
|
|
mod.widgets.HwPanel.draw_bg.ground = #x010408
|
|
mod.widgets.HwPanel.draw_bg.light_ink = vec4(0.55, 0.92, 1.0, 1.0)
|
|
mod.widgets.HwPanel.draw_bg.shadow_ink = vec4(0.0, 0.0, 0.0, 1.0)
|
|
mod.widgets.HwPanel.draw_bg.inner = vec4(0.85, 10.0, 0.0, 0.55)
|
|
mod.widgets.HwPanel.draw_bg.finish = vec4(0.5, 0.25, 0.06, 0.10)
|
|
mod.widgets.HwPanel.draw_bg.tune = vec4(0.04, 0.0, 1.10, 3.0)
|
|
mod.widgets.HwPanel.draw_bg.glow_ink = vec4(0.25, 0.90, 1.0, 1.0)
|
|
mod.widgets.HwPanel.draw_bg.spill = vec2(1.1, 0.4)
|
|
mod.widgets.HwPanel.draw_bg.edge_ink = vec4(0.30, 0.85, 1.0, 0.6)
|
|
mod.widgets.HwPanel.draw_bg.pixel = fn() {
|
|
let p = self.pos * self.rect_size
|
|
var o = self.layer(self.surface(p, self.ground.xyz))
|
|
let px = 1.0 / max(self.draw_pass.dpi_factor, 0.5)
|
|
let d = self.sd(p) + 0.8
|
|
let qe = min(min(p.x, p.y), min(self.rect_size.x - p.x, self.rect_size.y - p.y))
|
|
let fade = smoothstep(0.0, max(self.inset, 1.0), qe)
|
|
let line = 1.0 - smoothstep(0.3, 0.3 + px * 1.5, abs(d))
|
|
let halo = exp(-abs(d) / 2.5) * 0.25 * fade
|
|
let ink = self.edge_ink.xyz * self.edge_ink.w
|
|
return vec4(o.xyz + ink * (line + halo), o.w)
|
|
}
|
|
|
|
// The screen's surround: a black glass well, a bright traced rim.
|
|
mod.widgets.HwBezel.radius = 8
|
|
mod.widgets.HwBezel.draw_bg.ground = #x010306
|
|
mod.widgets.HwBezel.draw_bg.light_ink = vec4(0.55, 0.92, 1.0, 1.0)
|
|
mod.widgets.HwBezel.draw_bg.shadow_ink = vec4(0.0, 0.0, 0.0, 1.0)
|
|
mod.widgets.HwBezel.draw_bg.inner = vec4(0.95, 12.0, 0.0, 0.55)
|
|
mod.widgets.HwBezel.draw_bg.finish = vec4(0.5, 0.25, 0.06, 0.10)
|
|
mod.widgets.HwBezel.draw_bg.tune = vec4(0.04, 0.0, 1.10, 3.0)
|
|
mod.widgets.HwBezel.draw_bg.relief = vec4(2.0, 0.4, 3.0, 0.25)
|
|
mod.widgets.HwBezel.draw_bg.glow_ink = vec4(0.25, 0.90, 1.0, 1.0)
|
|
mod.widgets.HwBezel.draw_bg.spill = vec2(1.4, 0.4)
|
|
mod.widgets.HwBezel.draw_bg.edge_ink = vec4(0.45, 0.95, 1.0, 1.0)
|
|
mod.widgets.HwBezel.draw_bg.pixel = fn() {
|
|
let p = self.pos * self.rect_size
|
|
var o = self.layer(self.surface(p, self.ground.xyz))
|
|
let px = 1.0 / max(self.draw_pass.dpi_factor, 0.5)
|
|
let d = self.sd(p) + 0.9
|
|
let qe = min(min(p.x, p.y), min(self.rect_size.x - p.x, self.rect_size.y - p.y))
|
|
let fade = smoothstep(0.0, max(self.inset, 1.0), qe)
|
|
let line = 1.0 - smoothstep(0.35, 0.35 + px * 1.5, abs(d))
|
|
let halo = exp(-abs(d) / 4.0) * 0.40 * fade
|
|
let ink = self.edge_ink.xyz * self.edge_ink.w
|
|
return vec4(o.xyz + mix(ink, vec3(1.0, 1.0, 1.0), 0.3) * line + ink * halo, o.w)
|
|
}
|
|
|
|
// The screen glass: fine raster lines, a cool reflection, no bulge.
|
|
// No dark rim or bulge over the picture: it reads clean and bright.
|
|
mod.widgets.HwGlass.draw_bg.glass = vec4(0.0, 0.07, 0.0, 0.0)
|
|
mod.widgets.HwGlass.draw_bg.tint = vec4(0.55, 0.92, 1.0, 0.0)
|
|
mod.widgets.HwGlass.draw_bg.radius = 6.0
|
|
// Over the picture: a projection field. Fine raster lines, HUD brackets of
|
|
// light in the corners, a thin inner frame, a cool sheet of reflection.
|
|
mod.widgets.HwGlass.draw_bg.pixel = fn() {
|
|
let p = self.pos * self.rect_size
|
|
let sz = self.rect_size
|
|
let c = sz * 0.5
|
|
let d = Material.sd_box(p, c, c, self.radius)
|
|
let px = 1.0 / max(self.draw_pass.dpi_factor, 0.5)
|
|
let cov = 1.0 - smoothstep(-px, px, d)
|
|
let dark = smoothstep(-30.0, 0.0, d) * self.glass.z
|
|
// The reflection: a soft diagonal sheet in the top half.
|
|
let r = smoothstep(0.62, 0.0, self.pos.y + (self.pos.x - 0.5) * 0.25) * self.glass.y
|
|
let rgb = self.tint.xyz * r
|
|
let al = clamp(dark * (1.0 - r) + r, 0.0, 1.0)
|
|
return vec4(rgb, al) * cov
|
|
}
|
|
|
|
// ---- keys: translucent glass, lit from inside ----
|
|
mod.widgets.HwKey.radius = 5
|
|
mod.widgets.HwKey.depth = 1.5
|
|
mod.widgets.HwKey.press = -1.5
|
|
mod.widgets.HwKey.draw_bg.ground = #x030d13
|
|
mod.widgets.HwKey.draw_bg.light_ink = vec4(0.35, 0.85, 1.0, 1.0)
|
|
mod.widgets.HwKey.draw_bg.shadow_ink = vec4(0.0, 0.0, 0.0, 1.0)
|
|
mod.widgets.HwKey.draw_bg.relief = vec4(1.5, 0.3, 1.5, 0.6)
|
|
mod.widgets.HwKey.draw_bg.finish = vec4(0.4, 0.35, 0.12, 0.08)
|
|
mod.widgets.HwKey.draw_bg.tune = vec4(0.10, 0.0, 1.10, 3.0)
|
|
mod.widgets.HwKey.draw_bg.shadow = vec4(0.6, 7.0, 1.0, 0.4)
|
|
mod.widgets.HwKey.draw_bg.inner = vec4(0.72, 9.0, 0.0, 0.10)
|
|
mod.widgets.HwKey.draw_bg.glow_ink = vec4(0.25, 0.90, 1.0, 1.0)
|
|
mod.widgets.HwKey.draw_bg.spill = vec2(1.7, 0.45)
|
|
mod.widgets.HwKey.emissive = vec4(0.25, 0.88, 1.0, 0.35)
|
|
mod.widgets.HwKey.draw_bg.led = vec4(8.0, 8.0, 2.0, 0.0)
|
|
mod.widgets.HwKey.draw_bg.critical_ink = vec4(1.0, 1.0, 1.0, 0.0)
|
|
mod.widgets.HwKey.draw_bg.pixel = fn() {
|
|
let p = self.pos * self.rect_size
|
|
let lit = clamp(self.lit, 0.0, 1.0)
|
|
let c = self.rect_size * 0.5
|
|
let d0 = self.sd(p)
|
|
// The glass carries light in from its edges and holds a soft core.
|
|
let rim_light = exp(min(d0, 0.0) / 5.0) * step(d0, 0.0)
|
|
let uv = p / max(self.rect_size, vec2(1.0, 1.0))
|
|
var base = self.key_face(p, self.ground.xyz)
|
|
base = base + self.glow_ink.xyz * (rim_light * (0.10 + 0.45 * lit) + (1.0 - uv.y) * 0.03 + lit * 0.03)
|
|
var o = self.layer(base)
|
|
let px = 1.0 / max(self.draw_pass.dpi_factor, 0.5)
|
|
let d = d0 + 0.7
|
|
let qe = min(min(p.x, p.y), min(self.rect_size.x - p.x, self.rect_size.y - p.y))
|
|
let fade = smoothstep(0.0, max(self.inset, 1.0), qe)
|
|
let line = 1.0 - smoothstep(0.3, 0.3 + px * 1.5, abs(d))
|
|
let crit = self.critical * 0.35
|
|
let power = 0.45 + 0.55 * lit + crit
|
|
let halo = exp(-max(d, 0.0) / (2.0 + 3.0 * lit)) * step(0.0, d) * (0.25 + 0.7 * lit) * fade
|
|
let ink = self.glow_ink.xyz
|
|
let core = mix(ink, vec3(1.0, 1.0, 1.0), 0.25 + 0.5 * lit)
|
|
return vec4(o.xyz + core * line * power + ink * halo, o.w) + vec4(self.dither() * step(0.002, o.w), 0.0)
|
|
}
|
|
mod.widgets.HwKeyButton.draw_text.color = #xa8f4ff
|
|
mod.widgets.HwKeyButton.draw_text.color_hover = #xffffff
|
|
mod.widgets.HwKeyButton.draw_text.color_down = #xffffff
|
|
mod.widgets.HwKeyText.draw_text.color = #xa8f4ff
|
|
mod.widgets.HwKeyText.draw_text.color_hover = #xffffff
|
|
mod.widgets.HwKeyText.draw_text.color_down = #xffffff
|
|
|
|
// ---- lights: cyan-white light bars ----
|
|
mod.widgets.HwDash.radius = 1
|
|
mod.widgets.HwDash.emissive = vec4(0.30, 0.90, 1.0, 9.0)
|
|
mod.widgets.HwDash.draw_bg.glow_ink = vec4(0.30, 0.92, 1.0, 1.0)
|
|
mod.widgets.HwDash.draw_bg.ground = #x010508
|
|
mod.widgets.HwDash.draw_bg.light_ink = vec4(0.30, 0.80, 1.0, 1.0)
|
|
mod.widgets.HwDash.draw_bg.relief = vec4(0.8, 0.3, 1.0, 0.2)
|
|
mod.widgets.HwDash.draw_bg.pixel = fn() {
|
|
let p = self.pos * self.rect_size
|
|
let px = 1.0 / max(self.draw_pass.dpi_factor, 0.5)
|
|
let d = self.sd(p)
|
|
let lit = clamp(self.lit, 0.0, 1.0)
|
|
let cov = 1.0 - smoothstep(-px, px, d)
|
|
// Off: an empty glass tube, only its outline traced.
|
|
let line = (1.0 - smoothstep(0.25, 0.25 + px * 1.5, abs(d + 0.5))) * 0.55
|
|
let fill = (1.0 - smoothstep(-px, px, d + 0.6)) * lit
|
|
let edge = min(min(p.x, p.y), min(self.rect_size.x - p.x, self.rect_size.y - p.y))
|
|
let bloom = exp(-max(d, 0.0) / 4.5) * 0.7 * lit * smoothstep(0.0, self.inset, edge) * (1.0 - cov)
|
|
let ink = self.glow_ink.xyz
|
|
var col = self.ground.xyz * cov + ink * line * (1.0 - fill)
|
|
col = mix(col, mix(ink, vec3(1.0, 1.0, 1.0), 0.45), fill)
|
|
return vec4(col + ink * bloom, cov) + vec4(self.dither() * cov, 0.0)
|
|
}
|
|
mod.widgets.HwLed.emissive = vec4(0.30, 0.90, 1.0, 4.0)
|
|
mod.widgets.HwLed.draw_bg.glow_ink = vec4(0.30, 0.92, 1.0, 1.0)
|
|
|
|
// ---- knob: a black glass lens in a ring of light points ----
|
|
mod.widgets.HwKnobFace.depth = 5.0
|
|
mod.widgets.HwKnobFace.draw_bg.ground = #x010609
|
|
mod.widgets.HwKnobFace.draw_bg.light_ink = vec4(0.30, 0.80, 1.0, 1.0)
|
|
mod.widgets.HwKnobFace.draw_bg.finish = vec4(0.5, 0.45, 0.10, 0.08)
|
|
mod.widgets.HwKnobFace.draw_bg.shadow_ink = vec4(0.0, 0.0, 0.0, 1.0)
|
|
mod.widgets.HwKnobFace.draw_bg.relief = vec4(5.0, 0.8, 5.0, 0.9)
|
|
mod.widgets.HwKnobFace.draw_bg.knob = vec4(0.0, 0.62, 0.0, 0.0)
|
|
mod.widgets.HwKnobFace.draw_bg.ptr_ink = vec4(0.85, 1.0, 1.0, 1.0)
|
|
mod.widgets.HwKnobFace.draw_bg.ring = vec4(41.0, 1.24, 1.1, 2.35619)
|
|
mod.widgets.HwKnobFace.draw_bg.led_off = vec4(0.03, 0.12, 0.16, 1.0)
|
|
mod.widgets.HwKnobFace.draw_bg.glow_ink = vec4(0.30, 0.92, 1.0, 1.0)
|
|
mod.widgets.HwKnobFace.draw_bg.shadow = vec4(0.7, 12.0, 1.0, 0.5)
|
|
mod.widgets.HwKnobFace.draw_bg.spill = vec2(0.45, 0.4)
|
|
mod.widgets.HwKnobFace.emissive = vec4(0.30, 0.90, 1.0, 0.35)
|
|
mod.widgets.HwKnobFace.draw_bg.surface = fn(p: vec2, base: vec3) -> vec3 {
|
|
let c = self.rect_size * 0.5
|
|
let r = min(c.x, c.y) - self.inset
|
|
let t = length(p - c) / max(r, 1.0)
|
|
// Concentric holographic rings, a light line at the rim.
|
|
let rings = 0.5 + 0.5 * sin(t * 60.0)
|
|
let rim = exp(-abs(t - 0.96) * 40.0)
|
|
let rim2 = exp(-abs(t - 0.62) * 60.0)
|
|
let core = exp(-t * t * 18.0)
|
|
return base + vec3(0.02, 0.12, 0.16) * rings * 0.5 * (1.0 - t) + vec3(0.30, 0.90, 1.0) * (rim * 0.9 + rim2 * 0.35 + core * 0.18)
|
|
}
|
|
|
|
// ---- meter: a projected arc gauge, left outer, right inner ----
|
|
// Two concentric arcs of light segments sweep from the left to the right
|
|
// over a polar grid, rising from a projector point at the foot of the dial.
|
|
mod.widgets.HwMeterFace.radius = 5
|
|
mod.widgets.HwMeterFace.draw_bg.ground = #x010408
|
|
mod.widgets.HwMeterFace.draw_bg.meter = vec4(0.0, 28.0, 1.0, 0.8)
|
|
mod.widgets.HwMeterFace.draw_bg.glow_ink = vec4(0.25, 0.90, 1.0, 1.0)
|
|
mod.widgets.HwMeterFace.draw_bg.hot_ink = vec4(0.95, 1.0, 1.0, 1.0)
|
|
mod.widgets.HwMeterFace.draw_bg.led_off = vec4(0.03, 0.13, 0.17, 1.0)
|
|
mod.widgets.HwMeterFace.draw_bg.spill = vec2(0.5, 0.3)
|
|
mod.widgets.HwMeterFace.draw_bg.light_ink = vec4(0.30, 0.78, 0.95, 1.0)
|
|
mod.widgets.HwMeterFace.draw_bg.shadow_ink = vec4(0.0, 0.0, 0.0, 1.0)
|
|
mod.widgets.HwMeterFace.draw_bg.finish = vec4(0.5, 0.25, 0.0, 0.10)
|
|
mod.widgets.HwMeterFace.draw_bg.tune = vec4(0.0, 0.0, 1.10, 3.0)
|
|
mod.widgets.HwMeterFace.draw_bg.relief = vec4(1.5, 0.4, 2.0, 0.2)
|
|
mod.widgets.HwMeterFace.emissive = vec4(0.30, 0.90, 1.0, 0.9)
|
|
mod.widgets.HwMeterFace.draw_bg.pixel = fn() {
|
|
let p = self.pos * self.rect_size
|
|
let px = 1.0 / max(self.draw_pass.dpi_factor, 0.5)
|
|
var o = self.layer(self.surface(p, self.ground.xyz))
|
|
let sdp = self.sd(p)
|
|
let inside = 1.0 - smoothstep(-px, px, sdp)
|
|
// The dial is projected tilted back: a half ellipse as wide as the
|
|
// window, its polar maths done in the unsquashed plane.
|
|
let piv = vec2(self.rect_size.x * 0.5, self.rect_size.y - self.inset - 4.0)
|
|
let bigx = self.rect_size.x * 0.5 - self.inset - 12.0
|
|
let bigy = piv.y - self.inset - 7.0
|
|
let squash = bigx / max(bigy, 1.0)
|
|
let q = (p - piv) * vec2(1.0, squash)
|
|
let rq = length(q)
|
|
let ang = atan2(q.x, -q.y)
|
|
let sweep = 1.52
|
|
let u = (ang + sweep) / (sweep * 2.0)
|
|
let big = bigx
|
|
let n = max(self.meter.y, 4.0)
|
|
let inarc = step(0.0, u) * step(u, 1.0) * step(0.0, 0.0 - q.y + 1.0)
|
|
// The polar floor: faint rings and spokes, brighter toward the rim.
|
|
var col = vec3(0.0, 0.0, 0.0)
|
|
let ringd = abs(fract(rq / (big * 0.25) + 0.5) - 0.5) * big * 0.25
|
|
let spoke = abs(fract(u * 10.0 + 0.5) - 0.5) * (sweep * 2.0 / 10.0) * rq
|
|
let floorg = (1.0 - smoothstep(0.2, 0.2 + px * 1.5, min(ringd, spoke))) * step(rq, big * 1.02) * inarc
|
|
col = col + vec3(0.05, 0.30, 0.40) * floorg * 0.35
|
|
// Two bands of segments: left outer, right inner.
|
|
let seg = floor(u * n)
|
|
let fs = fract(u * n)
|
|
let cellw = sweep * 2.0 / n * rq
|
|
let da = min(fs, 1.0 - fs) * cellw
|
|
let gapm = smoothstep(0.55 - px, 0.55 + px, da)
|
|
let l0 = big * 0.78
|
|
let l1 = big * 1.0
|
|
let r0 = big * 0.52
|
|
let r1 = big * 0.72
|
|
let inL = (1.0 - smoothstep(-px, px, max(l0 - rq, rq - l1)))
|
|
let inR = (1.0 - smoothstep(-px, px, max(r0 - rq, rq - r1)))
|
|
let cpos = (seg + 0.5) / n
|
|
let onL = step(cpos, self.level.x)
|
|
let onR = step(cpos, self.level.y)
|
|
let hot = smoothstep(0.62, 0.95, cpos) * self.meter.z
|
|
let litc = mix(self.glow_ink.xyz, self.hot_ink.xyz, hot)
|
|
let offc = self.led_off.xyz
|
|
let mL = inL * gapm * inarc
|
|
let mR = inR * gapm * inarc
|
|
col = mix(col, mix(offc, litc * 1.25, onL), mL)
|
|
col = mix(col, mix(offc, litc * 1.25, onR), mR)
|
|
// Bloom round lit segments, along the radius.
|
|
let bl = exp(-max(max(l0 - rq, rq - l1), 0.0) / 3.0) * onL * (1.0 - inL)
|
|
let br = exp(-max(max(r0 - rq, rq - r1), 0.0) / 3.0) * onR * (1.0 - inR)
|
|
col = col + litc * (bl + br) * 0.35 * inarc
|
|
// The scale: a hairline arc outside, ticks every tenth, a hot zone.
|
|
let sc = big + 3.5
|
|
let arc = (1.0 - smoothstep(0.25, 0.25 + px * 1.5, abs(rq - sc))) * inarc
|
|
let tk = abs(fract(u * 10.0 + 0.5) - 0.5) * (sweep * 2.0 / 10.0) * rq
|
|
let tick = (1.0 - smoothstep(0.3, 0.3 + px * 1.5, tk)) * step(sc, rq) * step(rq, sc + 3.0) * inarc
|
|
col = col + mix(vec3(0.3, 0.85, 1.0), vec3(1.0, 1.0, 1.0), step(0.8, u)) * (arc * 0.55 + tick * 0.7)
|
|
// The projector: a bright point at the pivot throwing a faint cone up.
|
|
let pr = exp(-rq / 2.5) * 1.2 + exp(-rq / 9.0) * 0.25
|
|
let cone = exp(-abs(q.x) / (2.0 + max(0.0 - q.y, 0.0) * 0.5)) * step(q.y, 0.0) * 0.06
|
|
col = col + vec3(0.40, 0.95, 1.0) * (pr + cone)
|
|
// Holographic raster over the whole dial.
|
|
let scan = 0.85 + 0.15 * sin(p.y * 3.14159 * 1.0)
|
|
col = col * scan
|
|
o = vec4(o.xyz + col * inside, o.w)
|
|
return vec4(o.xyz + self.dither() * step(0.002, o.w), o.w)
|
|
}
|
|
|
|
// ---- the spectrum: light columns over a projected floor ----
|
|
// The visualiser draws its well, rules, bar slots, bars and peak marks with
|
|
// one rounded-box shader; its colour, corner radius and size tell them apart.
|
|
// Parts by `self.part` (1 well, 2 rule, 3 slot, 4 bar, 5 peak, 6 midline).
|
|
mod.widgets.HwSpectrum.draw_round.pixel = fn() {
|
|
let p = self.pos * self.rect_size
|
|
let sz = self.rect_size
|
|
let px = 1.0 / max(self.draw_pass.dpi_factor, 0.5)
|
|
let r = min(self.radius, min(sz.x, sz.y) * 0.5)
|
|
let c = sz * 0.5
|
|
let bq = abs(p - c) - c + vec2(r, r)
|
|
let d = length(max(bq, vec2(0.0, 0.0))) + min(max(bq.x, bq.y), 0.0) - r
|
|
let cov = 1.0 - smoothstep(-px, px, d)
|
|
if self.part > 0.5 && self.part < 1.5 {
|
|
// The well: black glass, a perspective floor of light lines toward
|
|
// a horizon, a hairline frame.
|
|
let uv = p / max(sz, vec2(1.0, 1.0))
|
|
var col = vec3(0.004, 0.014, 0.022)
|
|
// The horizon sits on the bars' baseline (the visualiser's layout).
|
|
let hy = (sz.y - 32.0) * 0.68 / max(sz.y, 1.0)
|
|
let depth = max(uv.y - hy, 0.0)
|
|
let fz = 1.0 / max(depth, 0.002)
|
|
let gz = abs(fract(fz * 0.9 + 0.5) - 0.5) / max(fz * fz * 0.9, 0.0001) * sz.y
|
|
let gx = abs(fract((uv.x - 0.5) * fz * 2.6 + 0.5) - 0.5) / max(fz * 2.6, 0.0001) * sz.x
|
|
let floorl = (1.0 - smoothstep(0.2, 0.2 + px * 1.6, min(gz, gx))) * step(hy, uv.y)
|
|
let fadef = smoothstep(0.0, 0.5, depth)
|
|
col = col + vec3(0.10, 0.55, 0.75) * floorl * (0.08 + 1.0 * fadef)
|
|
let horizon = exp(-abs(uv.y - hy) * sz.y / 1.5) * 0.35 + exp(-abs(uv.y - hy) * sz.y / 30.0) * 0.08
|
|
col = col + vec3(0.25, 0.85, 1.0) * horizon
|
|
let frame = 1.0 - smoothstep(0.3, 0.3 + px * 1.5, abs(d + 1.0))
|
|
col = col + vec3(0.25, 0.85, 1.0) * frame * 0.5
|
|
return vec4(col * cov, cov)
|
|
}
|
|
if (self.part > 1.5 && self.part < 2.5) || (self.part > 5.5 && self.part < 6.5) {
|
|
// Level rules: dotted light.
|
|
let dotm = step(0.5, fract(p.x / 4.0))
|
|
let a = cov * 0.45 * dotm
|
|
return vec4(vec3(0.25, 0.80, 1.0) * a, a)
|
|
}
|
|
// Segments, counted up from the foot of the column.
|
|
let yb = sz.y - p.y
|
|
let fsg = fract(yb / 4.0)
|
|
let segd = min(fsg, 1.0 - fsg) * 4.0
|
|
let segm = smoothstep(0.45 - px, 0.45 + px, segd)
|
|
if self.part > 2.5 && self.part < 3.5 {
|
|
// An empty slot: a ghost of the column.
|
|
let a = cov * segm * 0.10
|
|
return vec4(vec3(0.25, 0.80, 1.0) * a, a)
|
|
}
|
|
if self.part > 4.5 && self.part < 5.5 {
|
|
// A peak mark: a white-hot tick.
|
|
let a = cov
|
|
return vec4(vec3(0.85, 1.0, 1.0) * a, a)
|
|
}
|
|
// A lit column: cyan light with a white-hot head.
|
|
let head = exp(-p.y / 5.0)
|
|
let core = 1.0 - abs(p.x / max(sz.x, 1.0) - 0.5) * 1.2
|
|
let lift = smoothstep(0.0, 110.0, yb)
|
|
let deep = mix(vec3(0.02, 0.45, 0.85), vec3(0.35, 0.95, 1.0), lift)
|
|
var col = deep * (0.75 + 0.45 * core) + vec3(0.8, 1.0, 1.0) * head * 0.9
|
|
let a = cov * mix(segm, 1.0, head * 0.6)
|
|
return vec4(col * a, a)
|
|
}
|
|
mod.widgets.HwSpectrum.draw_line.pixel = fn() {
|
|
let p = self.pos * self.rect_size
|
|
let a = self.seg_a
|
|
let b = self.seg_b
|
|
let pa = p - a
|
|
let ba = b - a
|
|
let h = clamp(dot(pa, ba) / max(dot(ba, ba), 0.0001), 0.0, 1.0)
|
|
let d = length(pa - ba * h)
|
|
let core = 1.0 - smoothstep(0.35, 1.0, d)
|
|
let halo = exp(-d / 1.1) * 0.35
|
|
let al = clamp(core + halo, 0.0, 1.0) * self.color.w
|
|
let col = mix(self.color.xyz, vec3(0.9, 1.0, 1.0), core * 0.6)
|
|
return vec4(col * al, al)
|
|
}
|
|
|
|
// ---- the picture's light ----
|
|
mod.widgets.HwSpectrum.light = 4.5
|
|
mod.widgets.HwMilk.light = 3.2
|
|
mod.widgets.HwMilk.light_knee = 1.2
|
|
|
|
// ---- type: light, not ink ----
|
|
mod.widgets.HwCaption.draw_text.color = #x5fd8ee
|
|
mod.widgets.HwCaption.draw_text.text_style = theme.font_bold{font_size: 8.0}
|
|
mod.widgets.HwTitle.draw_text.color = #xe6fdff
|
|
mod.widgets.HwText.draw_text.color = #x8fe6f5
|
|
mod.widgets.HwPanelTitle.draw_text.color = #xd6fbff
|
|
mod.widgets.HwPanelText.draw_text.color = #x6fc2d2
|
|
mod.widgets.HwNavButton.draw_text.color = #xa8f0ff
|
|
mod.widgets.HwDisplayText.draw_text.color = #x9ff3ff
|
|
|
|
// Small displays: the progress strip, the equalizer.
|
|
mod.widgets.HwDisplay.radius = 5
|
|
mod.widgets.HwDisplay.draw_bg.ground = #x010408
|
|
mod.widgets.HwDisplay.draw_bg.light_ink = vec4(0.55, 0.92, 1.0, 1.0)
|
|
mod.widgets.HwDisplay.draw_bg.shadow_ink = vec4(0.0, 0.0, 0.0, 1.0)
|
|
mod.widgets.HwDisplay.draw_bg.inner = vec4(0.85, 9.0, 0.0, 0.55)
|
|
mod.widgets.HwDisplay.draw_bg.finish = vec4(0.5, 0.25, 0.06, 0.10)
|
|
mod.widgets.HwDisplay.draw_bg.tune = vec4(0.04, 0.0, 1.10, 3.0)
|
|
mod.widgets.HwDisplay.draw_bg.relief = vec4(1.5, 0.4, 2.0, 0.25)
|
|
mod.widgets.HwDisplay.draw_bg.spill = vec2(0.8, 0.4)
|
|
mod.widgets.HwDisplay.draw_bg.edge_ink = vec4(0.30, 0.85, 1.0, 0.7)
|
|
|
|
// Choosers and the search field: black glass, a cyan rim.
|
|
mod.widgets.HwDropDown.draw_bg.well = vec4(0.005, 0.02, 0.03, 1.0)
|
|
mod.widgets.HwDropDown.draw_bg.rim = vec4(0.35, 0.92, 1.0, 0.55)
|
|
mod.widgets.HwDropDown.draw_bg.arrow = vec4(0.45, 0.95, 1.0, 1.0)
|
|
mod.widgets.HwDropDown.draw_text.color = #xa8f4ff
|
|
mod.widgets.HwDropDown.draw_text.color_hover = #xffffff
|
|
mod.widgets.HwTextInput.draw_bg.well = vec4(0.005, 0.02, 0.03, 1.0)
|
|
mod.widgets.HwTextInput.draw_bg.rim = vec4(0.35, 0.92, 1.0, 0.55)
|
|
mod.widgets.HwTextInput.draw_text.color = #xd9fbff
|
|
|
|
mod.widgets.HwSegmented.draw_bg.well = vec4(0.005, 0.02, 0.03, 1.0)
|
|
mod.widgets.HwSegmented.draw_bg.rim = vec4(0.35, 0.92, 1.0, 0.55)
|
|
mod.widgets.HwSegmented.draw_pill.cap = vec4(0.30, 0.90, 1.0, 0.22)
|
|
mod.widgets.HwSegmented.draw_pill.glow = vec4(0.30, 0.92, 1.0, 1.0)
|
|
|
|
mod.widgets.HwSplitter.draw_bg.groove = vec4(0.0, 0.0, 0.0, 0.5)
|
|
mod.widgets.HwSplitter.draw_bg.glint = vec4(0.35, 0.92, 1.0, 0.7)
|
|
|
|
mod.widgets.HwArtBlank.draw_bg.vinyl = vec4(0.01, 0.03, 0.05, 1.0)
|
|
mod.widgets.HwArtBlank.draw_bg.groove = 0.25
|
|
// No art: a holographic data disc, light rings over black, a rainbow
|
|
// diffraction sheen across it and a lit hub.
|
|
mod.widgets.HwArtBlank.draw_bg.pixel = fn() {
|
|
let p = self.pos * self.rect_size
|
|
let c = self.rect_size * 0.5
|
|
let px = 1.0 / max(self.draw_pass.dpi_factor, 0.5)
|
|
var col = vec3(0.004, 0.012, 0.02)
|
|
let r = min(c.x, c.y) - 5.0
|
|
let q = p - c
|
|
let d = length(q)
|
|
let t = d / max(r, 1.0)
|
|
let disc = 1.0 - smoothstep(r - px, r + px, d)
|
|
let ang = atan2(q.y, q.x)
|
|
let rings = 0.5 + 0.5 * sin(d * 2.4)
|
|
let spec = pow(abs(cos(ang - 0.8)), 8.0)
|
|
let h = t * 6.0 + ang * 0.5
|
|
let irid = vec3(0.5 + 0.5 * sin(h + 3.6), 0.5 + 0.5 * sin(h + 1.2), 0.5 + 0.5 * sin(h))
|
|
var dc = vec3(0.01, 0.03, 0.045) + vec3(0.03, 0.12, 0.16) * rings * 0.35 + irid * spec * 0.22 * smoothstep(0.3, 0.5, t)
|
|
let rim = 1.0 - smoothstep(0.3, 0.3 + px * 1.5, abs(d - r + 0.6))
|
|
let tr = 1.0 - smoothstep(0.3, 0.3 + px * 1.5, abs(d - r * 0.36))
|
|
dc = dc + vec3(0.30, 0.90, 1.0) * (rim * 0.9 + tr * 0.6)
|
|
let hub = exp(-d / 3.0) * 1.2 + exp(-d / 10.0) * 0.2
|
|
dc = dc + vec3(0.40, 0.95, 1.0) * hub
|
|
col = mix(col, dc, disc)
|
|
return vec4(col + self.dither(), 1.0)
|
|
}
|
|
true
|
|
|
|
// ---- EQ (HwEqGraph: the graphic equalizer's era look, STYLE_GUIDE "Graphic EQ") ----
|
|
mod.widgets.HwEqGraph.draw_fader.fader = vec4(3.0, 0.50, 8.0, 3.0)
|
|
mod.widgets.HwEqGraph.draw_fader.track_ink = vec4(0.05, 0.20, 0.26, 1.0)
|
|
mod.widgets.HwEqGraph.draw_curve.curve = vec4(0.0, 1.6, 12.0, 0.12)
|
|
mod.widgets.HwEqGraph.draw_grid.grid = vec4(1.0, 0.30, 0.30, 0.0)
|
|
mod.widgets.HwEqGraph.draw_spectrum.spectrum = vec4(0.22, 1.0, 0.0, 0.0)
|
|
mod.widgets.HwEqGraph.light = 1.6
|
|
true
|