Mercurial > code > home > repos > light9
diff web/fade/Light9FadeUi.ts @ 2376:4556eebe5d73
topdir reorgs; let pdm have its src/ dir; separate vite area from light9/
author | drewp@bigasterisk.com |
---|---|
date | Sun, 12 May 2024 19:02:10 -0700 |
parents | light9/web/fade/Light9FadeUi.ts@06bf6dae8e64 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/fade/Light9FadeUi.ts Sun May 12 19:02:10 2024 -0700 @@ -0,0 +1,169 @@ +import debug from "debug"; +import { css, html, LitElement, TemplateResult } from "lit"; +import { customElement, property } from "lit/decorators.js"; +import * as N3 from "n3"; +import { NamedNode, Quad } from "n3"; +import { Patch } from "../patch"; +import { getTopGraph } from "../RdfdbSyncedGraph"; +import { showRoot } from "../show_specific"; +import { SyncedGraph } from "../SyncedGraph"; +export { EditChoice } from "../EditChoice"; +export { Light9EffectFader } from "./Light9EffectFader"; +export { Light9Fader } from "./Light9Fader"; + +debug.enable("*,autodep"); +const log = debug("fade"); + +class FaderConfig { + constructor(public uri: NamedNode, public column: number) { } +} + +class FadePage { + constructor(public uri: NamedNode) { } + faderConfigs: FaderConfig[] = []; +} +class FadePages { + pages: FadePage[] = []; +} + +@customElement("light9-fade-ui") +export class Light9FadeUi extends LitElement { + static styles = [ + css` + :host { + display: block; + user-select: none; /* really this is only desirable during slider drag events */ + } + .mappedToHw { + background: #393945; + } + #gm light9-fader { + width: 300px; + } + `, + ]; + render() { + return html` + <rdfdb-synced-graph></rdfdb-synced-graph> + + <h1>Fade</h1> +<div id="gm"> + <light9-fader .value=${this.grandMaster} @change=${this.gmChanged}></light9-fader>grand master +</div> + ${(this.fadePages?.pages || []).map(this.renderPage.bind(this))} + + <div><button @click=${this.addPage}>Add new page</button></div> + `; + } + private renderPage(page: FadePage): TemplateResult { + const mappedToHw = this.currentHwPage !== undefined && page.uri.equals(this.currentHwPage); + return html`<div class="${mappedToHw ? "mappedToHw" : ""}"> + <fieldset> + <legend> + Page + <resource-display rename .uri=${page.uri}></resource-display> + ${mappedToHw ? html`mapped to hardware sliders` : html` + <button @click=${(ev: Event) => this.mapThisToHw(page.uri)}>Map this to hw</button> + `} + </legend> + ${page.faderConfigs.map((fd) => html` <light9-effect-fader .uri=${fd.uri}></light9-effect-fader> `)} + </fieldset> + </div>`; + } + + graph!: SyncedGraph; + ctx: NamedNode = new NamedNode(showRoot + "/fade"); + + @property() fadePages?: FadePages; + @property() currentHwPage?: NamedNode; + @property() grandMaster?: number; + + constructor() { + super(); + getTopGraph().then((g) => { + this.graph = g; + this.graph.runHandler(this.compile.bind(this), `faders layout`); + this.graph.runHandler(this.compileGm.bind(this), `faders gm`); + }); + } + connectedCallback(): void { + super.connectedCallback(); + } + + compile() { + const U = this.graph.U(); + this.fadePages = undefined; + const fadePages = new FadePages(); + for (let page of this.graph.subjects(U("rdf:type"), U(":FadePage"))) { + const fp = new FadePage(page as NamedNode); + try { + for (let fader of this.graph.objects(page, U(":fader"))) { + const colLit = this.graph.stringValue(fader, U(':column')) + fp.faderConfigs.push(new FaderConfig(fader as NamedNode, parseFloat(colLit))); + } + fp.faderConfigs.sort((a, b) => { + return a.column - (b.column); + }); + fadePages.pages.push(fp); + } catch (e) { } + } + fadePages.pages.sort((a, b) => { + return a.uri.value.localeCompare(b.uri.value); + }); + this.fadePages = fadePages; + this.currentHwPage = undefined; + try { + const mc = this.graph.uriValue(U(":midiControl"), U(":map")); + this.currentHwPage = this.graph.uriValue(mc, U(":outputs")); + } catch (e) { } + } + compileGm() { + const U = this.graph.U(); + this.grandMaster = undefined + let newVal + try { + + newVal = this.graph.floatValue(U(':grandMaster'), U(':value')) + } catch (e) { + return + } + this.grandMaster = newVal; + + } + gmChanged(ev: CustomEvent) { + const U = this.graph.U(); + const newVal = ev.detail.value + // this.grandMaster = newVal; + this.graph.patchObject(U(':grandMaster'), U(':value'), this.graph.LiteralRoundedFloat(newVal), this.ctx) + + } + + + mapThisToHw(page: NamedNode) { + const U = this.graph.U(); + log("map to hw", page); + const mc = this.graph.uriValue(U(":midiControl"), U(":map")); + this.graph.patchObject(mc, U(":outputs"), page, this.ctx); + } + + addPage() { + const U = this.graph.U(); + const uri = this.graph.nextNumberedResource(showRoot + "/fadePage"); + const adds = [ + // + new Quad(uri, U("rdf:type"), U(":FadePage"), this.ctx), + new Quad(uri, U("rdfs:label"), N3.DataFactory.literal("unnamed"), this.ctx), + ]; + for (let n = 1; n <= 8; n++) { + const f = this.graph.nextNumberedResource(showRoot + "/fader"); + const s = this.graph.nextNumberedResource(showRoot + "/faderset"); + adds.push(new Quad(uri, U(":fader"), f, this.ctx)); + adds.push(new Quad(f, U("rdf:type"), U(":Fader"), this.ctx)); + adds.push(new Quad(f, U(":column"), N3.DataFactory.literal("" + n), this.ctx)); + adds.push(new Quad(f, U(":setting"), s, this.ctx)); + adds.push(new Quad(s, U(":effectAttr"), U(":strength"), this.ctx)); + adds.push(new Quad(s, U(":value"), this.graph.LiteralRoundedFloat(0), this.ctx)); + } + this.graph.applyAndSendPatch(new Patch([], adds)); + } +}