Changeset - ed0db55f604c
[Not reviewed]
default
0 3 0
drewp@bigasterisk.com - 20 months ago 2023-06-01 21:20:40
drewp@bigasterisk.com
use undefined for 'nothing selected' insetad of null
3 files changed with 12 insertions and 9 deletions:
0 comments (0 inline, 0 general)
light9/fade/Light9FadeUi.ts
Show inline comments
 
@@ -46,133 +46,133 @@ export class Light9FadeUi extends LitEle
 
      this.faders = [
 
        g.Uri(`:show/${shortShow}/fadePage1f0`),
 
        g.Uri(`:show/${shortShow}/fadePage1f1`),
 
        g.Uri(`:show/${shortShow}/fadePage1f2`),
 
        g.Uri(`:show/${shortShow}/fadePage1f3`),
 
        g.Uri(`:show/${shortShow}/fadePage1f4`),
 
        g.Uri(`:show/${shortShow}/fadePage1f5`),
 
        g.Uri(`:show/${shortShow}/fadePage1f6`),
 
        g.Uri(`:show/${shortShow}/fadePage1f7`),
 
      ];
 
    });
 
  }
 
  connectedCallback(): void {
 
    super.connectedCallback();
 
    meter = new FPSMeter(this.shadowRoot?.querySelector("#fps")!, { graph: 1, left: "auto", right: "0" });
 
    meter.tick();
 
  }
 
}
 

	
 
@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: 4px;
 
        width: 100%;
 
      }
 
    `,
 
  ];
 
  render() {
 
    return html`
 
      <light9-fader .value=${this.value} @change=${this.onSliderInput}></light9-fader>
 
      <div>${this.value.toPrecision(3)}</div>
 
      <div>eff: <edit-choice .uri=${this.effect} @edited=${this.onEffectChange}></edit-choice></div>
 
      <div>attr: <edit-choice .uri=${this.effectAttr} @edited=${this.onEffectAttrChange}></edit-choice></div>
 
      <div>&lt;=&gt; Slider ${this.column}</div>
 
    `;
 
  }
 

	
 
  graph?: SyncedGraph;
 
  ctx: NamedNode = new NamedNode(showRoot + "/fade");
 
  @property() uri!: NamedNode;
 
  @property() column!: string;
 
  @property() effect: NamedNode | null = null;
 
  @property() effectAttr: NamedNode | null = null;
 
  @state() setting: NamedNode | null = null;
 
  @property() effect?: NamedNode;
 
  @property() effectAttr?: NamedNode
 
  @state() setting?: NamedNode;
 

	
 
  @property() value: number = 0.0;
 

	
 
  constructor() {
 
    super();
 
    getTopGraph().then((g) => {
 
      this.graph = g;
 
      this.graph.runHandler(this.compile.bind(this, this.graph), `config ${this.uri.value}`);
 
      this.graph.runHandler(this.compileValue.bind(this, this.graph), `valueSync ${this.uri.value}`);
 
    });
 
  }
 

	
 
  private compile(graph: SyncedGraph) {
 
    const U = graph.U();
 
    if (!graph.contains(this.uri, U("rdf:type"), U(":Fader"))) {
 
      // not loaded yet, perhaps
 
      this.column = "unset";
 
      this.effect = null;
 
      this.effectAttr = null;
 
      this.effect = undefined;
 
      this.effectAttr = undefined;
 
      return;
 
    }
 
    this.column = graph.stringValue(this.uri, U(":column"));
 
    this.effect = graph.uriValue(this.uri, U(":effect"));
 
    this.setting = graph.uriValue(this.uri, U(":setting"));
 
    if (this.setting !== null) {
 
    if (this.setting !== undefined) {
 
      try {
 
        this.effectAttr = graph.uriValue(this.setting, U(":effectAttr"));
 
      } catch (e) {
 
        this.effectAttr = null;
 
        this.effectAttr = undefined;
 
      }
 
    }
 
  }
 

	
 
  private compileValue(graph: SyncedGraph) {
 
    const U = graph.U();
 
    if (!graph.contains(this.uri, U("rdf:type"), U(":Fader"))) {
 
      // not loaded yet
 
      // console.timeEnd(`valueSync ${this.uri.value}`)
 
      return;
 
    }
 
    const st = graph.uriValue(this.uri, U(":setting"));
 
    this.value = graph.floatValue(st, graph.Uri(":value"));
 
  }
 

	
 
  onSliderInput(ev: CustomEvent) {
 
    if (this.graph === undefined) {
 
      return;
 
    }
 
    const U = this.graph.U();
 
    const prev = this.value;
 
    const v: number = ev.detail.value;
 
    this.value = parseFloat(v.toPrecision(3)); // rewrite pls
 
    if (this.value == prev) {
 
      return;
 
    }
 
    meter.tick();
 
    if (!this.setting) {
 
      throw new Error("can't make new settings yet");
 
    }
 
    this.graph.patchObject(this.setting, this.graph.Uri(":value"), this.graph.LiteralRoundedFloat(this.value), 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 === null) {
 
    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);
 
  }
 
}
light9/web/ResourceDisplay.ts
Show inline comments
 
@@ -53,98 +53,101 @@ export class ResourceDisplay extends Lit
 

	
 
  render() {
 
    let renameDialog = html``;
 
    if (this.renameDialogOpen) {
 
      renameDialog = html` <mwc-dialog id="renameDialog" open @closing=${this.onRenameClosing} @closed=${this.onRenameClosed}>
 
        <p>
 
          New label:
 
          <mwc-textfield id="renameField" dialogInitialFocus .value=${this.renameTo}></mwc-textfield>
 
        </p>
 
        <mwc-button dialogAction="cancel" slot="secondaryAction">Cancel</mwc-button>
 
        <mwc-button dialogAction="ok" slot="primaryAction">OK</mwc-button>
 
      </mwc-dialog>`;
 
    }
 

	
 
    return html` <span class="${this.resClasses()}">
 
        <a href="${this.href()}" id="uri"> <!-- type icon goes here -->${this.label}</a>
 
        ${this.rename ? html`<button @click=${this.onRename}>Rename</button>` : ""} </span
 
      >${renameDialog}`;
 
    //
 
  }
 
  @property() uri?: NamedNode;
 

	
 
  @state() label: string = "";
 
  @state() renameDialogOpen = false;
 
  @state() renameTo = "";
 

	
 
  @property({ type: Boolean }) rename: boolean = false;
 
  @property({ type: Boolean }) noclick: boolean = false;
 
  @property({ type: Boolean }) minor: boolean = false;
 

	
 
  constructor() {
 
    super();
 
    getTopGraph().then((g) => {
 
      this.graph = g;
 
      this.onUri();
 
    });
 
  }
 

	
 
  updated(changedProperties: PropertyValues) {
 
    if (changedProperties.has("uri")) {
 
      this.onUri();
 
    }
 
  }
 

	
 
  private onUri() {
 
    if (!this.graph) {
 
      return; /*too soon, but getTopGraph will call us again*/
 
    }
 
    
 
    if (this.uri === undefined) {
 
      this.label = "(unset)";
 
    } else if  (this.uri === null) {
 
      throw 'use undefined please'
 
    } else {
 
      this.graph.runHandler(this.compile.bind(this, this.graph), `label for ${this.uri.id}`);
 
    }
 
  }
 
  private compile(graph: SyncedGraph) {
 
    if (this.uri === undefined) {
 
      return;
 
    } else {
 
      this.label = this.graph.labelOrTail(this.uri);
 
    }
 
  }
 

	
 
  private href(): string {
 
    if (!this.uri || this.noclick) {
 
      return "javascript:;";
 
    }
 
    return this.uri.value;
 
  }
 

	
 
  private resClasses() {
 
    return this.minor ? "resource minor" : "resource";
 
  }
 

	
 
  private onRename() {
 
    this.renameTo = this.label;
 
    this.renameDialogOpen = true;
 
    setTimeout(() => {
 
      // I! 👏 know! 👏 the! 👏 element! 👏 I! 👏 want!
 
      const inputEl = this.shadowRoot!.querySelector("#renameField")!.shadowRoot!.querySelector("input")! as HTMLInputElement;
 
      inputEl.setSelectionRange(0, -1);
 
    }, 100);
 
  }
 

	
 
  // move to SyncedGraph
 
  private whatCtxHeldTheObj(subj: NamedNode, pred: NamedNode): NamedNode {
 
    var ctxs = this.graph.contextsWithPattern(subj, pred, null);
 
    if (ctxs.length != 1) {
 
      throw new Error(`${ctxs.length} ${pred.id} stmts for ${subj.id}`);
 
    }
 
    return ctxs[0];
 
  }
 

	
 
  private onRenameClosing(ev: CustomEvent) {
 
    this.renameTo = (this.shadowRoot!.querySelector("#renameField")! as TextField).value;
 
  }
 

	
 
  private onRenameClosed(ev: CustomEvent) {
 
    this.renameDialogOpen = false;
tsconfig.json
Show inline comments
 
{
 
  "compilerOptions": {
 
    /* Visit https://aka.ms/tsconfig.json to read more about this file */
 

	
 
    /* Basic Options */
 
    // "incremental": true,                         /* Enable incremental compilation */
 
    "target": "es2020",                             /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
 
    "module": "es2020",                             /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
 
    // "lib": [],                                   /* Specify library files to be included in the compilation. */
 
    // "allowJs": true,                             /* Allow javascript files to be compiled. */
 
    // "checkJs": true,                             /* Report errors in .js files. */
 
    // "jsx": "preserve",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
 
    // "declaration": true,                         /* Generates corresponding '.d.ts' file. */
 
    // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
 
    // "sourceMap": true,                           /* Generates corresponding '.map' file. */
 
    // "outFile": "./",                             /* Concatenate and emit output to single file. */
 
    // "outDir": "./",                              /* Redirect output structure to the directory. */
 
    // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
 
    // "composite": true,                           /* Enable project compilation */
 
    // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
 
    // "removeComments": true,                      /* Do not emit comments to output. */
 
    // "noEmit": true,                              /* Do not emit outputs. */
 
    // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
 
    // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
 
    // "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
 

	
 
    /* Strict Type-Checking Options */
 
    "strict": true,                                 /* Enable all strict type-checking options. */
 
    // "noImplicitAny": true,                       /* Raise error on expressions and declarations with an implied 'any' type. */
 
    // "strictNullChecks": true,                    /* Enable strict null checks. */
 
    "strictNullChecks": true,                    /* Enable strict null checks. */
 
    // "strictFunctionTypes": true,                 /* Enable strict checking of function types. */
 
    // "strictBindCallApply": true,                 /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
 
    // "strictPropertyInitialization": true,        /* Enable strict checking of property initialization in classes. */
 
    // "noImplicitThis": true,                      /* Raise error on 'this' expressions with an implied 'any' type. */
 
    // "alwaysStrict": true,                        /* Parse in strict mode and emit "use strict" for each source file. */
 

	
 
    /* Additional Checks */
 
    // "noUnusedLocals": true,                      /* Report errors on unused locals. */
 
    // "noUnusedParameters": true,                  /* Report errors on unused parameters. */
 
    // "noImplicitReturns": true,                   /* Report error when not all code paths in function return a value. */
 
    // "noFallthroughCasesInSwitch": true,          /* Report errors for fallthrough cases in switch statement. */
 
    // "noUncheckedIndexedAccess": true,            /* Include 'undefined' in index signature results */
 
    // "noPropertyAccessFromIndexSignature": true,  /* Require undeclared properties from index signatures to use element accesses. */
 

	
 
    /* Module Resolution Options */
 
    "moduleResolution": "node"                      /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
 
    "baseUrl": "./"                                 /* Base directory to resolve non-absolute module names. */,
 
    "paths": {                                      /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
 
      "sylvester": ["light9/web/lib/sylvester.d.ts"],
 
      "onecolor": ["light9/web/lib/onecolor.d.ts"]
 
    },
 
    // "rootDirs": [],                              /* List of root folders whose combined content represents the structure of the project at runtime. */
 
    // "typeRoots": ["/my/proj/light9/light9/web/homepage"],                             /* List of folders to include type definitions from. */
 
    // "types": [],                                 /* Type declaration files to be included in compilation. */
 
    "allowSyntheticDefaultImports": true,        /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
 
    "esModuleInterop": true,                        /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
 
    // "preserveSymlinks": true,                    /* Do not resolve the real path of symlinks. */
 
    // "allowUmdGlobalAccess": true,                /* Allow accessing UMD globals from modules. */
 

	
 
    /* Source Map Options */
 
    // "sourceRoot": "",                            /* Specify the location where debugger should locate TypeScript files instead of source locations. */
 
    // "mapRoot": "",                               /* Specify the location where debugger should locate map files instead of generated locations. */
 
    // "inlineSourceMap": true,                     /* Emit a single file with source maps instead of having a separate file. */
 
    // "inlineSources": true,                       /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
 

	
 
    /* Experimental Options */
 
    "experimentalDecorators": true,              /* Enables experimental support for ES7 decorators. */
 
    // "emitDecoratorMetadata": true,               /* Enables experimental support for emitting type metadata for decorators. */
 

	
 
    /* Advanced Options */
 
    "skipLibCheck": true,                           /* Skip type checking of declaration files. */
 
    "forceConsistentCasingInFileNames": true,       /* Disallow inconsistently-cased references to the same file. */
 
    "useDefineForClassFields": false
 
  }
 
}
0 comments (0 inline, 0 general)