Changeset - 91ae65157e5f
[Not reviewed]
default
0 5 0
drewp@bigasterisk.com - 20 months ago 2023-05-25 18:46:08
drewp@bigasterisk.com
logging and comments
5 files changed with 13 insertions and 8 deletions:
0 comments (0 inline, 0 general)
light9/live/Effect.ts
Show inline comments
 
import debug from "debug";
 
import { Literal, NamedNode, Quad_Object, Quad_Predicate, Quad_Subject, Term } from "n3";
 
import { some } from "underscore";
 
import { Patch, patchContainsPreds, patchUpdate } from "../web/patch";
 
import { SyncedGraph } from "../web/SyncedGraph";
 
import { shortShow } from "../web/show_specific";
 

	
 
// todo: Align these names with newtypes.py, which uses HexColor and VTUnion.
 
type Color = string;
 
export type ControlValue = number | Color | NamedNode;
 

	
 
const log = debug("effect");
 

	
 
function isUri(x: Term | number | string): x is NamedNode {
 
  return typeof x == "object" && x.termType == "NamedNode";
 
}
 

	
 
function valuePred(graph: SyncedGraph, attr: NamedNode): NamedNode {
 
  const U = graph.U();
 
  const scaledAttributeTypes = [U(":color"), U(":brightness"), U(":uv")];
 
  if (some(scaledAttributeTypes, (x: NamedNode) => attr.equals(x))) {
 
    return U(":scaledValue");
 
  } else {
 
    return U(":value");
 
  }
 
}
 

	
 
// effect settings data; r/w sync with the graph
 
export class Effect {
 
  private settings: Array<{ device: NamedNode; deviceAttr: NamedNode; setting: NamedNode; value: ControlValue }> = [];
 
  private ctxForEffect: NamedNode
 
  constructor(
light9/live/Light9DeviceControl.ts
Show inline comments
 
@@ -63,51 +63,52 @@ export class Light9DeviceControl extends
 
        border-top-right-radius: 15px;
 
      }
 

	
 
      #mainLabel {
 
        font-size: 120%;
 
        color: #9ab8fd;
 
        text-decoration: initial;
 
      }
 
      .device.selected h2 {
 
        outline: 3px solid #ffff0047;
 
      }
 
      .deviceAttr.selected {
 
        background: #cada1829;
 
      }
 
    `,
 
  ];
 

	
 
  render() {
 
    return html`
 
      <div class="device ${this.devClasses}">
 
        <h2 style="${this._bgStyle(this.deviceClass)}" xon-click="onClick">
 
          <resource-display id="mainLabel" .uri="${this.uri}"></resource-display>
 
          a <resource-display minor .uri="${this.deviceClass}"></resource-display>
 
        </h2>
 

	
 
        ${this.deviceAttrs.map(
 
          (dattr: DeviceAttrRow) => html`
 
            <div xon-click="onAttrClick" class="deviceAttr ${dattr.attrClasses}">
 
            <div @click="onAttrClick" class="deviceAttr ${dattr.attrClasses}">
 
              <span>attr <resource-display minor .uri="${dattr.uri}"></resource-display></span>
 
              <light9-live-control
 
                .device="${this.uri}"
 
                .deviceAttrRow="${dattr}"
 
                .effect="${this.effect}"
 
                .graphToControls="${this.graphToControls}"
 
              ></light9-live-control>
 
            </div>
 
          `
 
        )}
 
      </div>
 
    `;
 
  }
 

	
 
  @property() uri!: NamedNode;
 
  @property() effect!: NamedNode;
 
  @property() graphToControls!: GraphToControls;
 

	
 
  @property() devClasses: string = ""; // the css kind
 
  @property() deviceAttrs: DeviceAttrRow[] = [];
 
  @property() deviceClass: NamedNode | null = null;
 
  @property() selectedAttrs: Set<NamedNode> = new Set();
 

	
 
  constructor() {
light9/live/Light9Listbox.ts
Show inline comments
 
import debug from "debug";
 
const log = debug("listbox");
 
import { css, html, LitElement, PropertyValues } from "lit";
 
import { customElement, property } from "lit/decorators.js";
 
export type Choice = {uri:string,label:string}
 
const log = debug("listbox");
 
export type Choice = { uri: string; label: string };
 

	
 
@customElement("light9-listbox")
 
export class Light9Listbox extends LitElement {
 
  static styles = [
 
    css`
 
      paper-listbox {
 
        --paper-listbox-background-color: none;
 
        --paper-listbox-color: white;
 
        --paper-listbox: {
 
          /* measure biggest item? use flex for columns? */
 
          column-width: 9em;
 
        }
 
      }
 
      paper-item {
 
        --paper-item-min-height: 0;
 
        --paper-item: {
 
          display: block;
 
          border: 1px outset #0f440f;
 
          margin: 0 1px 5px 0;
 
          background: #0b1d0b;
 
        }
 
      }
 
      paper-item.iron-selected {
 
        background: #7b7b4a;
 
      }
light9/live/Light9LiveControl.ts
Show inline comments
 
import debug from "debug";
 
const log = debug("control");
 
import { css, html, LitElement, PropertyPart, PropertyValues } from "lit";
 
import { css, html, LitElement, PropertyValues } from "lit";
 
import { customElement, property } from "lit/decorators.js";
 
import { NamedNode } from "n3";
 
import { getTopGraph } from "../web/RdfdbSyncedGraph";
 
import { Literal, NamedNode } from "n3";
 
import { SyncedGraph } from "../web/SyncedGraph";
 
import { ControlValue } from "./Effect";
 
import { GraphToControls } from "./GraphToControls";
 
import { DeviceAttrRow } from "./Light9DeviceControl";
 
import { Choice } from "./Light9Listbox";
 

	
 
const log = debug("control");
 

	
 
export { Slider } from "@material/mwc-slider";
 
// UI for one device attr (of any type).
 
@customElement("light9-live-control")
 
export class Light9LiveControl extends LitElement {
 
  graph!: SyncedGraph;
 

	
 
  static styles = [
 
    css`
 
      #colorControls {
 
        display: flex;
 
        align-items: center;
 
      }
 
      #colorControls > * {
 
        margin: 0 3px;
 
      }
 
      #colorControls paper-slider {
 
      }
 
      paper-slider {
 
        width: 100%;
 
        height: 25px;
 
      }
 

	
 
      paper-slider {
 
        --paper-slider-knob-color: var(--paper-red-500);
 
        --paper-slider-active-color: var(--paper-red-500);
 

	
light9/live/Light9LiveControls.ts
Show inline comments
 
@@ -78,49 +78,49 @@ export class Light9LiveControls extends 
 
      this.graphToControls = new GraphToControls(this.graph);
 
      // this.graph.runHandler(this.xupdate.bind(this), "Light9LiveControls update");
 
      this.setEffectFromUrl();
 
    });
 
  }
 

	
 
  updated(changedProperties: PropertyValues) {
 
    if (changedProperties.has("effectChoice")) {
 
      log(`effectChoice to ${this.effectChoice?.value}`);
 
      this.onEffectChoice();
 
    }
 
  }
 

	
 
  findDevices(patch?: Patch) {
 
    const U = this.graph.U();
 
    if (patch && !patchContainsPreds(patch, [U("rdf:type")])) {
 
      return;
 
    }
 

	
 
    this.devices = [];
 
    let classes = this.graph.subjects(U("rdf:type"), U(":DeviceClass"));
 
    log(`found ${classes.length} device classes`);
 
    uniq(sortBy(classes, "value"), true).forEach((dc) => {
 
      sortBy(this.graph.subjects(U("rdf:type"), dc), "value").forEach((dev) => {
 
        log(`found dev ${dev.value}`)
 
        log(`found dev ${dev.value}`);
 
        this.devices.push(dev as NamedNode);
 
      });
 
    });
 
    this.requestUpdate();
 
  }
 

	
 
  setEffectFromUrl() {
 
    // not a continuous bidi link between url and effect; it only reads
 
    // the url when the page loads.
 
    const effect = new URL(window.location.href).searchParams.get("effect");
 
    if (effect != null) {
 
      log(`found effect in url ${effect}`);
 
      this.effectChoice = this.graph.Uri(effect);
 
    }
 
    this.okToWriteUrl = true;
 
  }
 

	
 
  writeToUrl(effect: NamedNode | null) {
 
    const effectStr = effect ? this.graph.shorten(effect) : "";
 
    if (!this.okToWriteUrl) {
 
      return;
 
    }
 
    const u = new URL(window.location.href);
 
    if ((u.searchParams.get("effect") || "") === effectStr) {
0 comments (0 inline, 0 general)