Skip to content
Flecs v4.1
script/18_mixer

  • Flecs Script

    View on GitHub

    // Script that shows how to create a mixer panel UI
    using flecs.script
    struct Position(x: f32, y: f32)
    struct Rect(width: f32, height: f32)
    struct Circle(radius: f32)
    struct Rgb(r: u8, g: u8, b: u8)
    struct Text(value: string, size: i32, align: string)
    const panelColor: Rgb = {46, 50, 58}
    const panelDarkColor: Rgb = {32, 35, 41}
    const panelLightColor: Rgb = {182, 188, 198}
    const accentColor: Rgb = {98, 168, 122}
    const textColor: Rgb = {214, 218, 224}
    const mutedColor: Rgb = {210, 104, 91}
    const soloColor: Rgb = {220, 181, 95}
    const hoverColor: Rgb = {60, 65, 75}
    const fontSize = 12
    template Toggle {
    prop label: string = "M"
    prop color: Rgb = mutedColor
    prop value: bool = false
    prop width = 34
    prop height = 24
    mut active = value
    mut hover = false
    bg {
    Position: {}
    Rect: {width, height}
    if active {
    Rgb: color
    } else if hover {
    Rgb: hoverColor
    } else {
    Rgb: panelDarkColor
    }
    }
    caption {
    Position: {y: 1}
    Text: {label, fontSize, "center"}
    if active && !hover {
    Rgb: panelDarkColor
    } else {
    Rgb: textColor
    }
    }
    async {
    while true {
    await on.enter(this)
    hover = true
    await on.leave(this)
    hover = false
    }
    }
    async {
    while true {
    await on.click(this)
    active = !active
    }
    }
    }
    template Fader {
    prop value: f32 = -6
    prop min: f32 = -60
    prop max: f32 = 6
    prop height = 150
    prop color: Rgb = accentColor
    mut level: f32 = math.clamp(value, min, max)
    mut hover = false
    const ratio = (level - min) / (max - min)
    const handleY = -height / 2 + ratio * height
    const padTop = 8
    const padBottom = 32
    bg {
    Position: {y: (padTop - padBottom) / 2}
    Rect: {60, height + padTop + padBottom}
    if hover {
    Rgb: hoverColor
    } else {
    Rgb: panelColor
    }
    }
    track {
    Position: {}
    Rect: {6, height}
    Rgb: panelDarkColor
    }
    fill {
    Position: {y: -height / 2 + ratio * height / 2}
    Rect: {6, ratio * height}
    Rgb: color
    }
    for i in 0..7 {
    {
    Position: {x: 23, y: -height / 2 + i * height / 6}
    Rect: {8, 1}
    Rgb: panelLightColor
    }
    }
    unity {
    Position: {x: -23, y: -height / 2 + (0 - min) / (max - min) * height}
    Text: {"0", 10, "center"}
    Rgb: textColor
    }
    handle {
    Position: {y: handleY}
    Rect: {30, 14}
    Rgb: panelLightColor
    line {
    Position: {}
    Rect: {24, 2}
    Rgb: panelDarkColor
    }
    }
    readout {
    Position: {y: -height / 2 - 24}
    Text: {"{level:.1} dB", fontSize, "center"}
    Rgb: textColor
    }
    async {
    while true {
    await on.enter(this)
    hover = true
    await on.leave(this)
    hover = false
    }
    }
    async {
    while true {
    const e = await on.drag(this)
    const trackY = e.local_y - padBottom
    const newRatio = math.clamp(trackY / height, 0, 1)
    level = min + newRatio * (max - min)
    }
    }
    }
    template Pan {
    prop value: f32 = 0
    prop width = 64
    mut pan: f32 = math.clamp(value, -1, 1)
    mut hover = false
    const pad = 6
    bg {
    Position: {}
    Rect: {width + pad * 2, 24}
    if hover {
    Rgb: hoverColor
    } else {
    Rgb: panelColor
    }
    }
    track {
    Position: {}
    Rect: {width, 3}
    Rgb: panelDarkColor
    }
    center {
    Position: {}
    Rect: {2, 10}
    Rgb: panelLightColor
    }
    handle {
    Position: {x: pan * width / 2}
    Circle: {5}
    Rgb: accentColor
    }
    left {
    Position: {x: -width / 2, y: 17}
    Text: {"L", 10, "center"}
    Rgb: textColor
    }
    right {
    Position: {x: width / 2, y: 17}
    Text: {"R", 10, "center"}
    Rgb: textColor
    }
    async {
    while true {
    await on.enter(this)
    hover = true
    await on.leave(this)
    hover = false
    }
    }
    async {
    while true {
    const e = await on.drag(this)
    const trackX = e.local_x - pad
    pan = math.clamp(trackX / width * 2 - 1, -1, 1)
    }
    }
    }
    template ChannelStrip {
    prop label: string = "INPUT"
    prop level: f32 = -6
    prop pan: f32 = 0
    prop master: bool = false
    prop color: Rgb = accentColor
    bg {
    Position: {}
    Rect: {100, 320}
    Rgb: panelColor
    }
    accent {
    Position: {y: 157}
    Rect: {100, 6}
    Rgb: color
    }
    name {
    Position: {y: 134}
    Text: {label, fontSize, "center"}
    Rgb: textColor
    }
    if master {
    stereo {
    Position: {y: 96}
    Text: {"STEREO OUT", 10, "center"}
    Rgb: panelLightColor
    }
    } else {
    Pan balance(value: pan) {
    Position: {y: 93}
    }
    }
    Fader gain(value: level, color: color) {
    Position: {y: -5}
    }
    if master {
    Toggle mute(label: "MUTE", width: 76) {
    Position: {y: -135}
    }
    } else {
    Toggle mute {
    Position: {x: -21, y: -135}
    }
    Toggle solo(label: "S", color: soloColor) {
    Position: {x: 21, y: -135}
    }
    }
    }
    template Mixer {
    prop title: string = "MIXER"
    bg {
    Position: {}
    Rect: {464, 384}
    Rgb: panelDarkColor
    }
    heading {
    Position: {x: -214, y: 171}
    Text: {title, 14, "left"}
    Rgb: textColor
    }
    ChannelStrip drums(label: "DRUMS", level: -6) {
    Position: {x: -162, y: -18}
    }
    ChannelStrip bass(label: "BASS", level: -9, pan: -0.15) {
    Position: {x: -54, y: -18}
    }
    ChannelStrip keys(label: "KEYS", level: -12, pan: 0.3) {
    Position: {x: 54, y: -18}
    }
    ChannelStrip master(label: "MASTER", level: 0, master: true, color: soloColor) {
    Position: {x: 162, y: -18}
    }
    }
    Mixer mixing_panel