import debug from "debug"; import { css, html, LitElement } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import { NamedNode, Quad } from "n3"; import { getTopGraph } from "../RdfdbSyncedGraph"; import { showRoot } from "../show_specific"; import { SyncedGraph } from "../SyncedGraph"; import { Patch } from "../patch"; import { Literal } from "n3"; export { Light9Fader } from "./Light9Fader"; const log = debug("efffader") ////////////////////////////////////// const RETURN_URI = new NamedNode(""); const RETURN_FLOAT = 1; function get2Step(returnWhat: T, graph: SyncedGraph, subj1: NamedNode, pred1: NamedNode, pred2: NamedNode): T | undefined { // ?subj1 ?pred1 ?x . ?x ?pred2 ?returned . let x: NamedNode; try { x = graph.uriValue(subj1, pred1); } catch (e) { return undefined; } try { if (typeof returnWhat === "object" && (returnWhat as NamedNode).termType == "NamedNode") { return graph.uriValue(x, pred2) as T; } else if (typeof returnWhat === "number") { return graph.floatValue(x, pred2) as T; } } catch (e) { return undefined; } } function set2Step( graph: SyncedGraph, // subj1: NamedNode, pred1: NamedNode, baseName: string, pred2: NamedNode, newObjLiteral: Literal ) { } function maybeUriValue(graph: SyncedGraph, s: NamedNode, p: NamedNode): NamedNode | undefined { try { return graph.uriValue(s, p); } catch (e) { return undefined; } } function maybeStringValue(graph: SyncedGraph, s: NamedNode, p: NamedNode): string | undefined { try { return graph.stringValue(s, p); } catch (e) { return undefined; } } function maybeFloatValue(graph: SyncedGraph, s: NamedNode, p: NamedNode): number | undefined { try { return graph.floatValue(s, p); } catch (e) { return undefined; } } ////////////////////////////////////// class EffectFader { constructor(public uri: NamedNode) { } column: string = "unset"; effect?: NamedNode; effectAttr?: NamedNode; // :strength setting?: NamedNode; // we assume fader always has exactly one setting value?: number; } @customElement("light9-effect-fader") export class Light9EffectFader extends LitElement { static styles = [ css` :host { display: inline-block; border: 2px gray outset; background: #272727; } light9-fader { margin: 0px; width: 100%; } `, ]; render() { if (this.conf === undefined || this.conf.value === undefined) { return html`...`; } return html`
${this.conf.value.toPrecision(3)}
effect
attr
`; } graph?: SyncedGraph; ctx: NamedNode = new NamedNode(showRoot + "/fade"); @property() uri!: NamedNode; @state() conf?: EffectFader; // compiled from graph constructor() { super(); getTopGraph().then((g) => { this.graph = g; this.graph.runHandler(this.compile.bind(this, this.graph), `fader config ${this.uri.value}`); }); } private compile(graph: SyncedGraph) { const U = graph.U(); this.conf = undefined; const conf = new EffectFader(this.uri); if (!graph.contains(this.uri, U("rdf:type"), U(":Fader"))) { // not loaded yet, perhaps return; } conf.column = maybeStringValue(graph, this.uri, U(":column")) || "unset"; conf.effect = maybeUriValue(graph, this.uri, U(":effect")); conf.effectAttr = get2Step(RETURN_URI, graph, this.uri, U(":setting"), U(":effectAttr")); this.conf = conf; graph.runHandler(this.compileValue.bind(this, graph, this.conf), `fader config.value ${this.uri.value}`); } private compileValue(graph: SyncedGraph, conf: EffectFader) { // external graph change -> conf.value const U = graph.U(); conf.value = get2Step(RETURN_FLOAT, graph, this.uri, U(":setting"), U(":value")); // since conf attrs aren't watched as property: this.requestUpdate() } onSliderInput(ev: CustomEvent) { // slider user input -> graph if (this.conf === undefined) return; this.conf.value = ev.detail.value this.writeValueToGraph() } writeValueToGraph() { // this.value -> graph if (this.graph === undefined) { return; } const U = this.graph.U(); if (this.conf === undefined) { return; } if (this.conf.value === undefined) { log(`value of ${this.uri} is undefined`) return; } log('writeValueToGraph', this.conf.value) const valueTerm = this.graph.LiteralRoundedFloat(this.conf.value); const settingNode = this.graph.uriValue(this.uri, U(":setting")); this.graph.patchObject(settingNode, this.graph.Uri(":value"), valueTerm, this.ctx); } onEffectChange(ev: CustomEvent) { if (this.graph === undefined) { return; } const { newValue } = ev.detail; this.graph.patchObject(this.uri, this.graph.Uri(":effect"), newValue, this.ctx); } onEffectAttrChange(ev: CustomEvent) { if (this.graph === undefined) { return; } // const { newValue } = ev.detail; // if (this.setting === undefined) { // this.setting = this.graph.nextNumberedResource(this.graph.Uri(":fade_set")); // this.graph.patchObject(this.uri, this.graph.Uri(":setting"), this.setting, this.ctx); // } // this.graph.patchObject(this.setting, this.graph.Uri(":effectAttr"), newValue, this.ctx); } }