Mercurial > code > home > repos > light9
changeset 1779:067da1234c8e
port /live to polymer2 and new n3 api, mostly
Ignore-this: 9ad2163496af176fc2b2825209de92ac
author | Drew Perttula <drewp@bigasterisk.com> |
---|---|
date | Mon, 04 Jun 2018 08:21:41 +0000 |
parents | 178b11c9a429 |
children | fbc94316c048 |
files | light9/web/lib/bower.json light9/web/live/elements.html light9/web/live/index.html light9/web/live/live.coffee |
diffstat | 4 files changed, 299 insertions(+), 281 deletions(-) [+] |
line wrap: on
line diff
--- a/light9/web/lib/bower.json Mon Jun 04 07:07:11 2018 +0000 +++ b/light9/web/lib/bower.json Mon Jun 04 08:21:41 2018 +0000 @@ -13,7 +13,7 @@ "jquery-ui": "~1.11.4", "jquery.columnizer": "https://github.com/adamwulf/Columnizer-jQuery-Plugin.git#^1.6.2", "knockout": "knockoutjs#^3.4.2", - "paper-button": "PolymerElements/paper-button#^2.1.0", + "paper-button": "PolymerElements/paper-button#^2.1.1", "paper-dialog": "PolymerElements/paper-dialog#^2.1.0", "paper-item": "PolymerElements/paper-item#2.1.0", "paper-listbox": "PolymerElements/paper-listbox#2.1.0", @@ -26,10 +26,18 @@ "shortcut": "http://www.openjs.com/scripts/events/keyboard_shortcuts/shortcut.js", "sylvester": "~0.1.3", "underscore": "~1.8.3", - "polymer": "Polymer/polymer#^2.0.0" + "polymer": "Polymer/polymer#^2.0.0", + "iron-flex-layout": "PolymerElements/iron-flex-layout#^2.0.3", + "iron-component-page": "PolymerElements/iron-component-page#^3.0.1", + "paper-header-panel": "PolymerElements/paper-header-panel#^2.1.0" }, "resolutions": { "webcomponentsjs": "^v1.1.0", - "polymer": "^2.0.0" + "polymer": "^2.0.0", + "iron-flex-layout": "^2.0.3", + "paper-button": "^2.1.1", + "iron-component-page": "^3.0.1", + "iron-doc-viewer": "^3.0.0", + "paper-header-panel": "^2.1.0" } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/light9/web/live/elements.html Mon Jun 04 08:21:41 2018 +0000 @@ -0,0 +1,259 @@ +<link rel="import" href="/lib/polymer/polymer.html"> + +<link rel="import" href="/lib/paper-slider/paper-slider.html"> +<link rel="import" href="/lib/paper-listbox/paper-listbox.html"> +<link rel="import" href="/lib/paper-item/paper-item.html"> +<link rel="import" href="/lib/iron-ajax/iron-ajax.html"> +<link rel="import" href="../light9-collector-client.html"> + +<link rel="import" href="../rdfdb-synced-graph.html"> +<link rel="import" href="../resource-display.html"> +<link rel="import" href="../light9-color-picker.html"> +<link rel="import" href="../edit-choice.html"> + +<dom-module id="light9-listbox"> + <template> + <style> + 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; + } + } + </style> + <paper-listbox id="list" + selected="{{value}}" + attr-for-selected="uri" + on-focus-changed="selectOnFocus" + > + <paper-item on-focus="selectOnFocus">None</paper-item> + <template is="dom-repeat" items="{{choices}}"> + <paper-item on-focus="selectOnFocus" uri="{{item.uri}}">{{item.label}}</paper-item> + </template> + </paper-listbox> + + </template> + <script> + HTMLImports.whenReady(function () { + Polymer({ + is: "light9-listbox", + properties: { + choices: { type: Array }, + value: { type: String, notify: true }, + }, + observers: ['onValue(value)'], + selectOnFocus: function(ev) { + if (ev.target.uri === undefined) { + // *don't* clear for this, or we can't cycle through all choices (including none) with up/down keys + //this.clear(); + //return; + } + this.value = ev.target.uri; + + }, + onValue: function(value) { + if (value === null) { + this.clear(); + } + }, + clear: function() { + this.async(function() { + this.querySelectorAll('paper-item').forEach( + function(item) { item.blur(); }); + this.value = undefined; + }.bind(this)); + + }, + + }); + }); + </script> +</dom-module> + +<dom-module id="light9-live-control"> + <template> + <style> + #colorControls { + display: flex; + align-items: center; + } + #colorControls > * { + margin: 0 3px; + } + #colorControls paper-slider { + + } + paper-slider { width: 100%; height: 25px; } + </style> + + <style is="custom-style"> + paper-slider { + --paper-slider-knob-color: var(--paper-red-500); + --paper-slider-active-color: var(--paper-red-500); + + --paper-slider-font-color: white; + --paper-slider-input: { + width: 75px; + + background: black; + display: inline-block; + } + } + + </style> + + <template is="dom-if" if="{{deviceAttr.useSlider}}"> + <paper-slider min="0" + max="{{deviceAttr.max}}" + step=".001" + editable + content-type="application/json" + value="{{sliderWriteValue}}" + immediate-value="{{immediateSlider}}"></paper-slider> + </template> + <template is="dom-if" if="{{deviceAttr.useColor}}"> + <div id="colorControls"> + <button on-click="goBlack">0.0</button> + <light9-color-picker color="{{value}}"></light9-color-picker> + + </div> + </template> + <template is="dom-if" if="{{deviceAttr.useChoice}}"> + <light9-listbox choices="{{deviceAttr.choices}}" value="{{value}}"> + </light9-listbox> + </template> + + </template> + +</dom-module> + +<dom-module id="light9-live-device-control"> + <template> + <style> + :host { + display: inline-block; + } + .device { + border: 2px solid #151e2d; + margin: 4px; + padding: 1px; + background: #171717; /* deviceClass gradient added later */ + break-inside: avoid-column; + width: 445px; + + } + .deviceAttr { + border-top: 1px solid #272727; + padding-bottom: 2px; + display: flex; + } + .deviceAttr > span { + + } + .deviceAttr > light9-live-control { + flex-grow: 1; + } + h2 { + font-size: 110%; + padding: 4px; + } + .device, h2 { + border-top-right-radius: 15px; + } + + #mainLabel { + font-size: 120%; + color: #9ab8fd; + text-decoration: initial; + } + </style> + <div class="device"> + <h2 style$="[[bgStyle]]"> + <resource-display id="mainLabel" graph="{{graph}}" uri="{{uri}}"></resource-display> + a <resource-display minor graph="{{graph}}" uri="{{deviceClass}}"></resource-display> + </h2> + <template is="dom-repeat" items="{{deviceAttrs}}" as="dattr"> + <div class="deviceAttr"> + <span>attr <resource-display minor graph="{{graph}}" uri="{{dattr.uri}}"></resource-display></span> + <light9-live-control device="{{uri}}" device-attr="{{dattr}}"></light9-live-control> + </div> + </template> + </div> + </template> +</dom-module> + +<dom-module id="light9-live-controls"> + <template> + <style> + :host { + display: flex; + flex-direction: column; + } + #preview { + width: 100%; + } + #deviceControls { + flex-grow: 1; + position: relative; + width: 100%; + overflow-y: auto; + } + + light9-live-device-control > div { + break-inside: avoid-column; + } + light9-live-device-control { + + } + </style> + <rdfdb-synced-graph graph="{{graph}}"></rdfdb-synced-graph> + + <light9-collector-client self="{{client}}"></light9-collector-client> + <h1>device control + <button on-click="resendAll">resend all</button> + <button on-click="clearAll">clear all</button></h1> + + <div id="save"> + <div> + effect name: <input type="input" value="{{newEffectName::change}}"> + <button on-click="saveNewEffect">save new effect</button> + <edit-choice graph="{{graph}}" uri="{{effect}}"></edit-choice> + </div> + <textarea id="preview" value="{{effectPreview}}"></textarea> + </div> + + <div id="deviceControls"> + <template is="dom-repeat" items="{{devices}}" as="device"> + <light9-live-device-control graph="{{graph}}" uri="{{device.uri}}"></light9-live-device-control> + </template> + </div> + + + </template> +</dom-module> + + +<script src="/lib/d3/build/d3.min.js"></script> +<script src="/node_modules/n3/n3-browser.js"></script> +<script src="/lib/async/dist/async.js"></script> +<script src="/lib/underscore/underscore-min.js"></script> +<script src="../coffee_element.js"></script> +<!-- see live.coffee + <script src="/lib/jquery/dist/jquery.js"></script> + <script src="/lib/isotope/dist/isotope.pkgd.min.js"></script> + <script src="/lib/isotope-fit-columns/fit-columns.js"></script> + <script src="/lib/jquery.columnizer/src/jquery.columnizer.js"></script> + --> + +<script src="live.js"></script>
--- a/light9/web/live/index.html Mon Jun 04 07:07:11 2018 +0000 +++ b/light9/web/live/index.html Mon Jun 04 08:21:41 2018 +0000 @@ -4,28 +4,8 @@ <title>device control</title> <meta charset="utf-8" /> <link rel="stylesheet" href="/style.css"> - <script src="/lib/webcomponentsjs/webcomponents-lite.min.js"></script> - <link rel="import" href="/lib/polymer/polymer.html"> - <link rel="import" href="/lib/paper-slider/paper-slider.html"> - <link rel="import" href="/lib/paper-listbox/paper-listbox.html"> - <link rel="import" href="/lib/paper-item/paper-item.html"> - <link rel="import" href="/lib/iron-ajax/iron-ajax.html"> - <link rel="import" href="../light9-collector-client.html"> - - <script src="/lib/d3/build/d3.min.js"></script> - <script src="/node_modules/n3/n3-browser.js"></script> - <script src="/lib/async/dist/async.js"></script> - <script src="/lib/underscore/underscore-min.js"></script> - <!-- see live.coffee - <script src="/lib/jquery/dist/jquery.js"></script> - <script src="/lib/isotope/dist/isotope.pkgd.min.js"></script> - <script src="/lib/isotope-fit-columns/fit-columns.js"></script> - <script src="/lib/jquery.columnizer/src/jquery.columnizer.js"></script> - --> - <link rel="import" href="../rdfdb-synced-graph.html"> - <link rel="import" href="../resource-display.html"> - <link rel="import" href="../light9-color-picker.html"> - <link rel="import" href="../edit-choice.html"> + <script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script> + <link rel="import" href="elements.html"> </head> <body> <style> @@ -40,239 +20,6 @@ bottom: 0; } </style> - <dom-module id="light9-listbox"> - <template> - <style> - 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; - } - } - </style> - <paper-listbox id="list" - selected="{{value}}" - attr-for-selected="uri" - on-focus-changed="selectOnFocus" - > - <paper-item on-focus="selectOnFocus">None</paper-item> - <template is="dom-repeat" items="{{choices}}"> - <paper-item on-focus="selectOnFocus" uri="{{item.uri}}">{{item.label}}</paper-item> - </template> - </paper-listbox> - - </template> - <script> - HTMLImports.whenReady(function () { - Polymer({ - is: "light9-listbox", - properties: { - choices: { type: Array }, - value: { type: String, notify: true }, - }, - observers: ['onValue(value)'], - selectOnFocus: function(ev) { - if (ev.target.uri === undefined) { - // *don't* clear for this, or we can't cycle through all choices (including none) with up/down keys - //this.clear(); - //return; - } - this.value = ev.target.uri; - - }, - onValue: function(value) { - if (value === null) { - this.clear(); - } - }, - clear: function() { - this.async(function() { - this.querySelectorAll('paper-item').forEach( - function(item) { item.blur(); }); - this.value = undefined; - }.bind(this)); - - }, - - }); - }); - </script> - </dom-module> - - <dom-module id="light9-live-control"> - <template> - <style> - #colorControls { - display: flex; - align-items: center; - } - #colorControls > * { - margin: 0 3px; - } - #colorControls paper-slider { - - } - paper-slider { width: 100%; height: 25px; } - </style> - - <style is="custom-style"> - paper-slider { - --paper-slider-knob-color: var(--paper-red-500); - --paper-slider-active-color: var(--paper-red-500); - - --paper-slider-font-color: white; - --paper-slider-input: { - width: 75px; - - background: black; - } - } - - </style> - - <template is="dom-if" if="{{deviceAttr.useSlider}}"> - <paper-slider min="0" - max="{{deviceAttr.max}}" - step=".001" - editable - content-type="application/json" - value="{{sliderWriteValue}}" - immediate-value="{{immediateSlider}}"></paper-slider> - </template> - <template is="dom-if" if="{{deviceAttr.useColor}}"> - <div id="colorControls"> - <button on-click="goBlack">0.0</button> - <light9-color-picker color="{{value}}"></light9-color-picker> - - </div> - </template> - <template is="dom-if" if="{{deviceAttr.useChoice}}"> - <light9-listbox choices="{{deviceAttr.choices}}" value="{{value}}"> - </light9-listbox> - </template> - - </template> - - </dom-module> - - <dom-module id="light9-live-device-control"> - <template> - <style> - :host { - display: inline-block; - } - .device { - border: 2px solid #151e2d; - margin: 4px; - padding: 1px; - background: #171717; /* deviceClass gradient added later */ - break-inside: avoid-column; - width: 445px; - - } - .deviceAttr { - border-top: 1px solid #272727; - padding-bottom: 2px; - display: flex; - } - .deviceAttr > span { - - } - .deviceAttr > light9-live-control { - flex-grow: 1; - } - h2 { - font-size: 110%; - padding: 4px; - } - .device, h2 { - border-top-right-radius: 15px; - } - - #mainLabel { - font-size: 120%; - color: #9ab8fd; - text-decoration: initial; - } - </style> - <div class="device"> - <h2 style$="[[bgStyle]]"> - <resource-display id="mainLabel" graph="{{graph}}" uri="{{uri}}"></resource-display> - a <resource-display minor graph="{{graph}}" uri="{{deviceClass}}"></resource-display> - </h2> - <template is="dom-repeat" items="{{deviceAttrs}}" as="dattr"> - <div class="deviceAttr"> - <span>attr <resource-display minor graph="{{graph}}" uri="{{dattr.uri}}"></resource-display></span> - <light9-live-control device="{{uri}}" device-attr="{{dattr}}"></light9-live-control> - </div> - </template> - </div> - </template> - </dom-module> - - <dom-module id="light9-live-controls"> - <template> - <style> - :host { - display: flex; - flex-direction: column; - } - #preview { - width: 100%; - } - #deviceControls { - flex-grow: 1; - position: relative; - width: 100%; - overflow-y: auto; - } - - light9-live-device-control > div { - break-inside: avoid-column; - } - light9-live-device-control { - - } - </style> - <rdfdb-synced-graph graph="{{graph}}"></rdfdb-synced-graph> - - <light9-collector-client self="{{client}}"></light9-collector-client> - <h1>device control - <button on-click="resendAll">resend all</button> - <button on-click="clearAll">clear all</button></h1> - - <div id="save"> - <div> - effect name: <input type="input" value="{{newEffectName::change}}"> - <button on-click="saveNewEffect">save new effect</button> - <edit-choice graph="{{graph}}" uri="{{effect}}"></edit-choice> - </div> - <textarea id="preview" value="{{effectPreview}}"></textarea> - </div> - - <div id="deviceControls"> - <template is="dom-repeat" items="{{devices}}" as="device"> - <light9-live-device-control graph="{{graph}}" uri="{{device.uri}}"></light9-live-device-control> - </template> - </div> - - - </template> - </dom-module> - <light9-live-controls></light9-live-controls> - - <script src="live.js"></script> </body> </html>
--- a/light9/web/live/live.coffee Mon Jun 04 07:07:11 2018 +0000 +++ b/light9/web/live/live.coffee Mon Jun 04 08:21:41 2018 +0000 @@ -1,8 +1,8 @@ log = console.log -Polymer - is: 'light9-live-control' - properties: +coffeeElementSetup(class Light9LiveControl extends Polymer.Element + @is: 'light9-live-control' + @getter_properties: device: { type: String } deviceAttr: { type: Object } max: { type: Number, value: 1 } @@ -11,11 +11,11 @@ immediateSlider: { notify: true, observer: 'onSlider' } sliderWriteValue: { type: Number } pickedChoice: { observer: 'onChange' } - observers: [ + @getter_observers: [ 'onChange(value)' ] ready: -> - + super.ready() onSlider: -> @value = @immediateSlider goBlack: -> @value = "#000000" onChange: (value) -> @@ -30,27 +30,29 @@ @value = '#000000' else @value = @immediateSlider = 0 +) -Polymer - is: "light9-live-device-control" - properties: +coffeeElementSetup(class Light9LiveDeviceControl extends Polymer.Element + @is: "light9-live-device-control" + @getter_properties: graph: { type: Object, notify: true } uri: { type: String, notify: true } deviceClass: { type: String, notify: true } deviceAttrs: { type: Array, notify: true } bgStyle: { type: String, computed: '_bgStyle(deviceClass)' } - observers: [ + @getter_observers: [ 'onGraph(graph)' ] _bgStyle: (deviceClass) -> hash = 0 + deviceClass = deviceClass.value for i in [(deviceClass.length-10)...deviceClass.length] hash += deviceClass.charCodeAt(i) hue = (hash * 8) % 360 accent = "hsl(#{hue}, 49%, 22%)" "background: linear-gradient(to right, rgba(31,31,31,0) 50%, #{accent} 100%);" onGraph: -> - @graph.runHandler(@update.bind(@), "#{@uri} update") + @graph.runHandler(@update.bind(@), "#{@uri.value} update") update: -> U = (x) => @graph.Uri(x) @@ -62,12 +64,12 @@ daRow = { uri: da dataType: dataType - showColorPicker: dataType == U(':color') + showColorPicker: dataType.equals(U(':color')) } - if dataType == 'http://light9.bigasterisk.com/color' + if dataType.equals(U(':color')) daRow.useColor = true - else if dataType == U(':choice') + else if dataType.equals(U(':choice')) daRow.useChoice = true choiceUris = _.sortBy(@graph.objects(da, U(':choice'))) daRow.choices = ({uri: x, label: @graph.labelOrTail(x)} for x in choiceUris) @@ -75,16 +77,16 @@ else daRow.useSlider = true daRow.max = 1 - if dataType == U(':angle') + if dataType.equals(U(':angle')) # varies daRow.max = 1 @push('deviceAttrs', daRow) - +) -Polymer - is: "light9-live-controls" - properties: +coffeeElementSetup(class Light9LiveControls extends Polymer.Element + @is: "light9-live-controls" + @getter_properties: graph: { type: Object, notify: true } client: { type: Object, notify: true } devices: { type: Array, notify: true } @@ -92,11 +94,12 @@ effectPreview: { type: String, notify: true } newEffectName: { type: String, notify: true } effect: { type: String, notify: true } # the one being edited, if any - observers: [ + @getter_observers: [ 'onGraph(graph)' 'onEffect(effect)' ] ready: -> + super.ready() @currentSettings = {} @effectPreview = JSON.stringify({}) @@ -104,7 +107,7 @@ window.gather = (sent) => [dev, devAttr, value] = sent[0] - key = dev + " " + devAttr + key = dev.value + " " + devAttr.value # this is a bug for zoom=0, since collector will default it to # stick at the last setting if we don't explicitly send the # 0. rx/ry similar though not the exact same deal because of @@ -149,16 +152,16 @@ U = (x) => @graph.Uri(x) - @effect = U(":effect") + "/#{uriName}" + @effect = U(U(":effect").value + "/#{uriName}") ctx = U("http://light9.bigasterisk.com/show/dance2017/effect/#{uriName}") - quad = (s, p, o) => {subject: s, predicate: p, object: o, graph: ctx} + quad = (s, p, o) => @graph.Quad(s, p, o, ctx) addQuads = [ quad(@effect, U('rdf:type'), U(':Effect')) quad(@effect, U('rdfs:label'), @graph.Literal(@newEffectName)) quad(@effect, U(':publishAttr'), U(':strength')) ] - settings = @graph.nextNumberedResources(@effect + '_set', @currentSettingsList().length) + settings = @graph.nextNumberedResources(@effect.value + '_set', @currentSettingsList().length) for row in @currentSettingsList() if row[2] == 0 or row[2] == '#000000' continue @@ -206,3 +209,4 @@ layoutMode: 'masonry', containerStyle: null })), 2000) +) \ No newline at end of file