comparison 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
comparison
equal deleted inserted replaced
2375:623836db99af 2376:4556eebe5d73
1 import debug from "debug";
2 import { css, html, LitElement, TemplateResult } from "lit";
3 import { customElement, property } from "lit/decorators.js";
4 import * as N3 from "n3";
5 import { NamedNode, Quad } from "n3";
6 import { Patch } from "../patch";
7 import { getTopGraph } from "../RdfdbSyncedGraph";
8 import { showRoot } from "../show_specific";
9 import { SyncedGraph } from "../SyncedGraph";
10 export { EditChoice } from "../EditChoice";
11 export { Light9EffectFader } from "./Light9EffectFader";
12 export { Light9Fader } from "./Light9Fader";
13
14 debug.enable("*,autodep");
15 const log = debug("fade");
16
17 class FaderConfig {
18 constructor(public uri: NamedNode, public column: number) { }
19 }
20
21 class FadePage {
22 constructor(public uri: NamedNode) { }
23 faderConfigs: FaderConfig[] = [];
24 }
25 class FadePages {
26 pages: FadePage[] = [];
27 }
28
29 @customElement("light9-fade-ui")
30 export class Light9FadeUi extends LitElement {
31 static styles = [
32 css`
33 :host {
34 display: block;
35 user-select: none; /* really this is only desirable during slider drag events */
36 }
37 .mappedToHw {
38 background: #393945;
39 }
40 #gm light9-fader {
41 width: 300px;
42 }
43 `,
44 ];
45 render() {
46 return html`
47 <rdfdb-synced-graph></rdfdb-synced-graph>
48
49 <h1>Fade</h1>
50 <div id="gm">
51 <light9-fader .value=${this.grandMaster} @change=${this.gmChanged}></light9-fader>grand master
52 </div>
53 ${(this.fadePages?.pages || []).map(this.renderPage.bind(this))}
54
55 <div><button @click=${this.addPage}>Add new page</button></div>
56 `;
57 }
58 private renderPage(page: FadePage): TemplateResult {
59 const mappedToHw = this.currentHwPage !== undefined && page.uri.equals(this.currentHwPage);
60 return html`<div class="${mappedToHw ? "mappedToHw" : ""}">
61 <fieldset>
62 <legend>
63 Page
64 <resource-display rename .uri=${page.uri}></resource-display>
65 ${mappedToHw ? html`mapped to hardware sliders` : html`
66 <button @click=${(ev: Event) => this.mapThisToHw(page.uri)}>Map this to hw</button>
67 `}
68 </legend>
69 ${page.faderConfigs.map((fd) => html` <light9-effect-fader .uri=${fd.uri}></light9-effect-fader> `)}
70 </fieldset>
71 </div>`;
72 }
73
74 graph!: SyncedGraph;
75 ctx: NamedNode = new NamedNode(showRoot + "/fade");
76
77 @property() fadePages?: FadePages;
78 @property() currentHwPage?: NamedNode;
79 @property() grandMaster?: number;
80
81 constructor() {
82 super();
83 getTopGraph().then((g) => {
84 this.graph = g;
85 this.graph.runHandler(this.compile.bind(this), `faders layout`);
86 this.graph.runHandler(this.compileGm.bind(this), `faders gm`);
87 });
88 }
89 connectedCallback(): void {
90 super.connectedCallback();
91 }
92
93 compile() {
94 const U = this.graph.U();
95 this.fadePages = undefined;
96 const fadePages = new FadePages();
97 for (let page of this.graph.subjects(U("rdf:type"), U(":FadePage"))) {
98 const fp = new FadePage(page as NamedNode);
99 try {
100 for (let fader of this.graph.objects(page, U(":fader"))) {
101 const colLit = this.graph.stringValue(fader, U(':column'))
102 fp.faderConfigs.push(new FaderConfig(fader as NamedNode, parseFloat(colLit)));
103 }
104 fp.faderConfigs.sort((a, b) => {
105 return a.column - (b.column);
106 });
107 fadePages.pages.push(fp);
108 } catch (e) { }
109 }
110 fadePages.pages.sort((a, b) => {
111 return a.uri.value.localeCompare(b.uri.value);
112 });
113 this.fadePages = fadePages;
114 this.currentHwPage = undefined;
115 try {
116 const mc = this.graph.uriValue(U(":midiControl"), U(":map"));
117 this.currentHwPage = this.graph.uriValue(mc, U(":outputs"));
118 } catch (e) { }
119 }
120 compileGm() {
121 const U = this.graph.U();
122 this.grandMaster = undefined
123 let newVal
124 try {
125
126 newVal = this.graph.floatValue(U(':grandMaster'), U(':value'))
127 } catch (e) {
128 return
129 }
130 this.grandMaster = newVal;
131
132 }
133 gmChanged(ev: CustomEvent) {
134 const U = this.graph.U();
135 const newVal = ev.detail.value
136 // this.grandMaster = newVal;
137 this.graph.patchObject(U(':grandMaster'), U(':value'), this.graph.LiteralRoundedFloat(newVal), this.ctx)
138
139 }
140
141
142 mapThisToHw(page: NamedNode) {
143 const U = this.graph.U();
144 log("map to hw", page);
145 const mc = this.graph.uriValue(U(":midiControl"), U(":map"));
146 this.graph.patchObject(mc, U(":outputs"), page, this.ctx);
147 }
148
149 addPage() {
150 const U = this.graph.U();
151 const uri = this.graph.nextNumberedResource(showRoot + "/fadePage");
152 const adds = [
153 //
154 new Quad(uri, U("rdf:type"), U(":FadePage"), this.ctx),
155 new Quad(uri, U("rdfs:label"), N3.DataFactory.literal("unnamed"), this.ctx),
156 ];
157 for (let n = 1; n <= 8; n++) {
158 const f = this.graph.nextNumberedResource(showRoot + "/fader");
159 const s = this.graph.nextNumberedResource(showRoot + "/faderset");
160 adds.push(new Quad(uri, U(":fader"), f, this.ctx));
161 adds.push(new Quad(f, U("rdf:type"), U(":Fader"), this.ctx));
162 adds.push(new Quad(f, U(":column"), N3.DataFactory.literal("" + n), this.ctx));
163 adds.push(new Quad(f, U(":setting"), s, this.ctx));
164 adds.push(new Quad(s, U(":effectAttr"), U(":strength"), this.ctx));
165 adds.push(new Quad(s, U(":value"), this.graph.LiteralRoundedFloat(0), this.ctx));
166 }
167 this.graph.applyAndSendPatch(new Patch([], adds));
168 }
169 }