Skip to content
Snippets Groups Projects

pop-up description

3 files
+ 597
534
Compare changes
  • Side-by-side
  • Inline

Files

+ 584
534
//
//
//
//
// new node controller / VIEW
// new node controller / VIEW
// reconfigurable unviersal numeric dataflow machine controller
// reconfigurable unviersal numeric dataflow machine controller
// 'RUN DMC'
// 'RUN DMC'
// dataflow numeric controller
// dataflow numeric controller
// DNC
// DNC
//
//
// client.js
// client.js
//
//
//
//
// Jake Read at the Center for Bits and Atoms
// Jake Read at the Center for Bits and Atoms
// (c) Massachusetts Institute of Technology 2018
// (c) Massachusetts Institute of Technology 2018
//
//
// This work may be reproduced, modified, distributed, performed, and
// This work may be reproduced, modified, distributed, performed, and
// displayed for any purpose, but must acknowledge the mods
// displayed for any purpose, but must acknowledge the mods
// project. Copyright is retained and must be preserved. The work is
// project. Copyright is retained and must be preserved. The work is
// provided as is; no warranty is provided, and users accept all
// provided as is; no warranty is provided, and users accept all
// liability.
// liability.
/*
/*
CLIENT GLOBALS ---------------------------------------------------
CLIENT GLOBALS ---------------------------------------------------
*/
*/
var sckt = {}
var sckt = {}
var lastPos = { x: 10, y: 30 }
var lastPos = { x: 10, y: 30 }
// drawing / div-ing
// drawing / div-ing
var wrapper = {}
var wrapper = {}
var nav = {}
var nav = {}
/*
/*
STARTUP ---------------------------------------------------
STARTUP ---------------------------------------------------
*/
*/
window.onload = function() {
window.onload = function() {
svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
svg.style.position = 'absolute'
svg.style.position = 'absolute'
svg.style.left = 0
svg.style.left = 0
svg.style.top = 0
svg.style.top = 0
svg.style.zIndex = 0
svg.style.zIndex = 0
svg.style.overflow = 'visible'
svg.style.overflow = 'visible'
svg.setAttribute('width', 2)
svg.setAttribute('width', 2)
svg.setAttribute('height', 2)
svg.setAttribute('height', 2)
svg.setAttribute('id', 'svg')
svg.setAttribute('id', 'svg')
svg.setAttribute('width', '100%')
svg.setAttribute('width', '100%')
svg.setAttribute('height', '100%')
svg.setAttribute('height', '100%')
document.body.appendChild(svg)
document.body.appendChild(svg)
wrapper = document.createElement('div')
wrapper = document.createElement('div')
wrapper.id = 'wrapper'
wrapper.id = 'wrapper'
document.body.append(wrapper)
document.body.append(wrapper)
nav = document.getElementById('nav')
nav = document.getElementById('nav')
const socket = new WebSocket('ws://localhost:8081')
const socket = new WebSocket('ws://localhost:8081')
socket.onopen = function(evt) {
socket.onopen = function(evt) {
// pass to global ref
// pass to global ref
sckt = this
sckt = this
// say hello
// say hello
socketSend('console', 'hello server')
socketSend('console', 'hello server')
console.log('socket open')
console.log('socket open')
// ask for the current program
// ask for the current program
socketSend('get current program', '')
socketSend('get current program', '')
// main socket entry point
// main socket entry point
this.onmessage = (evt) => {
this.onmessage = (evt) => {
socketRecv(evt)
socketRecv(evt)
}
}
// others
// others
this.onerror = (err) => {
this.onerror = (err) => {
alert('link to server is broken')
alert('link to server is broken')
location.reload()
location.reload()
console.log('socket error', err)
console.log('socket error', err)
}
}
this.onclose = (evt) => {
this.onclose = (evt) => {
console.log('socket closed', evt)
console.log('socket closed', evt)
sckt = null
sckt = null
 
}
}
}
}
}
}
/*
/*
RECV / SEND PORTALS ---------------------------------------------------
RECV / SEND PORTALS ---------------------------------------------------
*/
*/
function socketSend(type, data) {
function socketSend(type, data) {
var msg = {
var msg = {
type: type,
type: type,
data: data
data: data
 
}
 
console.log('SEND', msg)
 
sckt.send(JSON.stringify(msg))
}
}
console.log('SEND', msg)
sckt.send(JSON.stringify(msg))
function socketRecv(evt) {
}
var recv = JSON.parse(evt.data)
var type = recv.type
function socketRecv(evt) {
var data = recv.data
var recv = JSON.parse(evt.data)
console.log('RECV', recv)
var type = recv.type
// tree banger
var data = recv.data
switch (type) {
console.log('RECV', recv)
case 'console':
// tree banger
console.log('RECV CONSOLE:', data)
switch (type) {
break
case 'console':
case 'put module menu':
console.log('RECV CONSOLE:', data)
console.log('RECV MODULE MENU')
break
heapSendsModuleMenu(data)
case 'put module menu':
break
console.log('RECV MODULE MENU')
case 'put program menu':
heapSendsModuleMenu(data)
console.log('RECV PRG MENU')
break
heapSendsProgramMenu(data)
case 'put program menu':
break
console.log('RECV PRG MENU')
case 'put program':
heapSendsProgramMenu(data)
console.log('RECV PROGRAM')
break
heapSendsNewProgram(data)
case 'put program':
break
console.log('RECV PROGRAM')
case 'put module':
heapSendsNewProgram(data)
console.log('RECV NEW MODULE')
break
heapSendsNewModule(data)
case 'put module':
break
console.log('RECV NEW MODULE')
case 'put module change':
heapSendsNewModule(data)
console.log('RECV MODULE CHANGE')
break
heapSendsModuleChange(data)
case 'put module change':
break
console.log('RECV MODULE CHANGE')
case 'put state change':
heapSendsModuleChange(data)
console.log('RECV STATE CHANGE')
break
heapSendsStateChange(data)
case 'put state change':
break
console.log('RECV STATE CHANGE')
case 'restart':
heapSendsStateChange(data)
location.reload()
break
default:
case 'restart':
console.log('ERR recv with non recognized type', recv)
location.reload()
break
default:
}
console.log('ERR recv with non recognized type', recv)
break
}
}
}
/*
/*
MISC ---------------------------------------------------
MISC ---------------------------------------------------
*/
*/
/*
/*
HEAP -> SERVER ---------------------------------------------------
HEAP -> SERVER ---------------------------------------------------
*/
*/
// always a rep, tho
// always a rep, tho
var program = {}
var program = {}
// re-writes the program, adds a description,
// re-writes the program, adds a description,
// and loads multiple representations of modules to the view
// and loads multiple representations of modules to the view
function heapSendsNewProgram(prgm) {
function heapSendsNewProgram(prgm) {
// whole hearted replace
// whole hearted replace
// hello for bugs when we lay this on top of something else
// hello for bugs when we lay this on top of something else
program = prgm
program = prgm
// 1st we want to git rm old files ...
// 1st we want to git rm old files ...
// when adding links, we'll have to add all and then draw links
// when adding links, we'll have to add all and then draw links
console.log(program)
console.log(program)
for (mdlName in program.modules) {
for (mdlName in program.modules) {
addRepToView(program.modules[mdlName])
addRepToView(program.modules[mdlName])
 
}
 
redrawLinks()
}
}
redrawLinks()
}
function heapSendsNewModule(mdl) {
function heapSendsNewModule(mdl) {
if (program.description == null) {
if (program.description == null) {
program.description.name = 'unnamed program'
program.description.name = 'unnamed program'
}
}
if (program.modules == null) {
if (program.modules == null) {
program.modules = {}
program.modules = {}
}
addRepToView(mdl)
program.modules[mdl.description.id] = mdl
redrawLinks()
}
// writes DOM elements to represent the module, appends to the wrapper
// and appends to the rep object a .ui object
// containing references to those DOM objects
function heapSendsModuleChange(data) {
console.log(data)
// data should be rep of changed module
var rep = program.modules[data.description.id]
// we want a general case, but for now we know we're looking for
// new event hookups or new state items
for (key in rep.outputs) {
var output = rep.outputs[key]
if (output.calls.length !== data.outputs[key].calls.length) {
rep.outputs = data.outputs
}
}
 
addRepToView(mdl)
 
program.modules[mdl.description.id] = mdl
 
redrawLinks()
}
}
// ok
for (key in rep.state) {
// writes DOM elements to represent the module, appends to the wrapper
var stateItem = rep.state[key]
// and appends to the rep object a .ui object
if (stateItem != data.state[key]) {
// containing references to those DOM objects
stateItem = data.state[key]
rep.ui.state[key].value = data.state[key]
function heapSendsModuleChange(data) {
 
console.log(data)
 
// data should be rep of changed module
 
var rep = program.modules[data.description.id]
 
// we want a general case, but for now we know we're looking for
 
// new event hookups or new state items
 
for (key in rep.outputs) {
 
var output = rep.outputs[key]
 
if (output.calls.length !== data.outputs[key].calls.length) {
 
rep.outputs = data.outputs
 
}
 
}
 
// ok
 
for (key in rep.state) {
 
var stateItem = rep.state[key]
 
if (stateItem != data.state[key]) {
 
stateItem = data.state[key]
 
rep.ui.state[key].value = data.state[key]
 
}
}
}
 
// wreckless or wonderful?
 
//clear(rep)
 
redrawLinks()
}
}
// wreckless or wonderful?
//clear(rep)
// update state from server to UI
redrawLinks()
function heapSendsStateChange(data) {
}
console.log('HEAP SENDS CHANGE STATE IN MODULE', data)
var rep = program.modules[data.id]
// update state from server to UI
rep.state[data.key] = data.val
function heapSendsStateChange(data) {
if (rep.state[data.key].type == 'multiline') {
console.log('HEAP SENDS CHANGE STATE IN MODULE', data)
rep.ui.state[data.key].value = data.val.value
var rep = program.modules[data.id]
} else {
rep.state[data.key] = data.val
rep.ui.state[data.key].value = data.val
if (rep.state[data.key].type == 'multiline') {
}
rep.ui.state[data.key].value = data.val.value
} else {
rep.ui.state[data.key].value = data.val
}
}
}
/*
/*
UI -> HEAP ---------------------------------------------------
UI -> HEAP ---------------------------------------------------
*/
*/
 
// push new state from UI to server
function putState(rep, key) {
var data = {
id: rep.description.id,
key: key,
val: rep.state[key]
}
socketSend('put state change', data)
}
// save ui position to server for reload
// push new state from UI to server
function putUi(rep) {
function putState(rep, key) {
var data = {
var data = {
description: {
id: rep.description.id,
id: rep.description.id,
position: {
key: key,
left: rep.description.position.left,
val: rep.state[key]
top: rep.description.position.top
}
}
}
 
socketSend('put state change', data)
}
}
socketSend('put ui change', data)
// save ui position to server for reload
}
function putUi(rep) {
// input / output click handling
var clkState = false
var oClk = {}
var tmpBz = {}
function evtConnectHandler(clk) {
if (!clkState) {
// first click
oClk = clk
clkState = true
} else {
// second click
var tClk = clk
//console.log(oClk, tClk)
var x1 = parseInt(oClk.evt.target.offsetParent.style.left, 10) + oClk.evt.target.offsetLeft + oClk.evt.target.clientWidth
var y1 = parseInt(oClk.evt.target.offsetParent.style.top, 10) + oClk.evt.target.offsetTop + oClk.evt.target.clientHeight / 2
var x2 = parseInt(tClk.evt.target.offsetParent.style.left, 10) + tClk.evt.target.offsetLeft
var y2 = parseInt(tClk.evt.target.offsetParent.style.top, 10) + tClk.evt.target.offsetTop + tClk.evt.target.clientHeight / 2
//var bz = newBezier(x1, y1, x2, y2)
clkState = false
//console.log('connect', oClk.rep.description.id, oClk.name, 'to', tClk.rep.description.id, tClk.name)
var data = {
var data = {
from: {
description: {
id: oClk.rep.description.id,
id: rep.description.id,
output: oClk.name
position: {
},
left: rep.description.position.left,
to: {
top: rep.description.position.top
id: tClk.rep.description.id,
}
input: tClk.name
}
 
}
 
 
socketSend('put ui change', data)
 
}
 
 
// input / output click handling
 
var clkState = false
 
var oClk = {}
 
var tmpBz = {}
 
 
function evtConnectHandler(clk) {
 
if (!clkState) {
 
// first click
 
oClk = clk
 
clkState = true
 
} else {
 
// second click
 
var tClk = clk
 
//console.log(oClk, tClk)
 
var x1 = parseInt(oClk.evt.target.offsetParent.style.left, 10) + oClk.evt.target.offsetLeft + oClk.evt.target.clientWidth
 
var y1 = parseInt(oClk.evt.target.offsetParent.style.top, 10) + oClk.evt.target.offsetTop + oClk.evt.target.clientHeight / 2
 
var x2 = parseInt(tClk.evt.target.offsetParent.style.left, 10) + tClk.evt.target.offsetLeft
 
var y2 = parseInt(tClk.evt.target.offsetParent.style.top, 10) + tClk.evt.target.offsetTop + tClk.evt.target.clientHeight / 2
 
//var bz = newBezier(x1, y1, x2, y2)
 
clkState = false
 
//console.log('connect', oClk.rep.description.id, oClk.name, 'to', tClk.rep.description.id, tClk.name)
 
var data = {
 
from: {
 
id: oClk.rep.description.id,
 
output: oClk.name
 
},
 
to: {
 
id: tClk.rep.description.id,
 
input: tClk.name
 
}
}
}
 
socketSend('put link change', data)
}
}
socketSend('put link change', data)
}
}
}
/*
/*
UTILITIES ---------------------------------------------------
UTILITIES ---------------------------------------------------
*/
*/
function isStateKey(key) {
function isStateKey(key) {
if (key.indexOf('_') == 0 || key == 'emitters' || key == 'onChange' || key == 'emitChange') {
if (key.indexOf('_') == 0 || key == 'emitters' || key == 'onChange' || key == 'emitChange') {
return false
return false
} else {
} else {
return true
return true
 
}
}
}
}
function redrawLinks() {
function redrawLinks() {
// probably not a great way to do this, we're removing everything
// probably not a great way to do this, we're removing everything
// svg -rm -r
// svg -rm -r
while (svg.firstChild) {
while (svg.firstChild) {
svg.removeChild(svg.firstChild)
svg.removeChild(svg.firstChild)
}
// find that link
var lnkPt
var nLnk = 0
for (mdlName in program.modules) {
if (program.modules[mdlName].description.isLink) {
lnkPt = getLeftWall(program.modules[mdlName].ui.domElem)
}
}
}
// find that link
// redraw thru all links, just look at reps
var lnkPt
for (mdlName in program.modules) {
var nLnk = 0
var mdlRep = program.modules[mdlName]
for (mdlName in program.modules) {
for (key in mdlRep.outputs) {
if (program.modules[mdlName].description.isLink) {
var output = mdlRep.outputs[key]
lnkPt = getLeftWall(program.modules[mdlName].ui.domElem)
var outputUi = mdlRep.ui.outputs[key]
for (input in output.calls) {
var toId = output.calls[input].parentId
var toKey = output.calls[input].key
var inputUi = program.modules[toId].ui.inputs[toKey]
var outPos = getOutputArrow(outputUi)
var inPos = getInputArrow(inputUi)
if (inputUi.isHovering || outputUi.isHovering) {
var bz = newBezier(outPos.x, outPos.y, inPos.x, inPos.y, true)
} else {
var bz = newBezier(outPos.x, outPos.y, inPos.x, inPos.y, false)
}
}
}
}
}
if (mdlRep.description.isHardware && !mdlRep.description.isLink) {
// redraw thru all links, just look at reps
nLnk++
for (mdlName in program.modules) {
var hwPt = getRightWall(mdlRep.ui.domElem)
var mdlRep = program.modules[mdlName]
lnkPt.y += 10 * nLnk
for (key in mdlRep.outputs) {
var ln = newLine(hwPt.x, hwPt.y, lnkPt.x, lnkPt.y)
var output = mdlRep.outputs[key]
 
var outputUi = mdlRep.ui.outputs[key]
 
for (input in output.calls) {
 
var toId = output.calls[input].parentId
 
var toKey = output.calls[input].key
 
var inputUi = program.modules[toId].ui.inputs[toKey]
 
var outPos = getOutputArrow(outputUi)
 
var inPos = getInputArrow(inputUi)
 
if (inputUi.isHovering || outputUi.isHovering) {
 
var bz = newBezier(outPos.x, outPos.y, inPos.x, inPos.y, true)
 
} else {
 
var bz = newBezier(outPos.x, outPos.y, inPos.x, inPos.y, false)
 
}
 
}
 
}
 
if (mdlRep.description.isHardware && !mdlRep.description.isLink) {
 
nLnk++
 
var hwPt = getRightWall(mdlRep.ui.domElem)
 
lnkPt.y += 10 * nLnk
 
var ln = newLine(hwPt.x, hwPt.y, lnkPt.x, lnkPt.y)
 
}
}
}
}
}
}
/*
/*
UI EVENTS ---------------------------------------------------------------------
UI EVENTS ---------------------------------------------------------------------
*/
*/
// drag / pan etc
// drag / pan etc
document.body.style.overflow = 'hidden'
document.body.style.overflow = 'hidden'
document.body.style.transform = 'scale(1) translate(0px, 0px)'
document.body.style.transform = 'scale(1) translate(0px, 0px)'
document.body.style.transformOrigin = '0px 0px'
document.body.style.transformOrigin = '0px 0px'
// s/o @ Neil
// s/o @ Neil
function getCurrentTransform() {
function getCurrentTransform() {
// a string
// a string
var transform = document.body.style.transform
var transform = document.body.style.transform
var index = transform.indexOf('scale')
var index = transform.indexOf('scale')
var left = transform.indexOf('(', index)
var left = transform.indexOf('(', index)
var right = transform.indexOf(')', index)
var right = transform.indexOf(')', index)
var s = parseFloat(transform.slice(left + 1, right))
var s = parseFloat(transform.slice(left + 1, right))
var index = transform.indexOf('translate')
var index = transform.indexOf('translate')
var left = transform.indexOf('(', index)
var left = transform.indexOf('(', index)
var right = transform.indexOf('px', left)
var right = transform.indexOf('px', left)
var tx = parseFloat(transform.slice(left + 1, right))
var tx = parseFloat(transform.slice(left + 1, right))
var left = transform.indexOf(',', right)
var left = transform.indexOf(',', right)
var right = transform.indexOf('px', left)
var right = transform.indexOf('px', left)
var ty = parseFloat(transform.slice(left + 1, right))
var ty = parseFloat(transform.slice(left + 1, right))
var origin = document.body.style.transformOrigin
var origin = document.body.style.transformOrigin
var pxx = origin.indexOf('px')
var pxx = origin.indexOf('px')
var ox = parseFloat(origin.slice(0, pxx))
var ox = parseFloat(origin.slice(0, pxx))
var pxy = origin.indexOf('px', pxx + 2)
var pxy = origin.indexOf('px', pxx + 2)
var oy = parseFloat(origin.slice(pxx + 2, pxy))
var oy = parseFloat(origin.slice(pxx + 2, pxy))
return ({
return ({
s: s,
s: s,
tx: tx,
tx: tx,
ty: ty,
ty: ty,
ox: ox,
ox: ox,
oy: oy
oy: oy
})
})
}
function elementIsNotModule(element) {
if ((element.tagName == 'HTML') || (element.tagName == 'BODY') || (element.tagName == 'svg')) {
return true
} else {
return false
}
}
}
onwheel = function(evt) {
function elementIsNotModule(element) {
var el = document.elementFromPoint(evt.pageX, evt.pageY)
if ((element.tagName == 'HTML') || (element.tagName == 'BODY') || (element.tagName == 'svg')) {
if (elementIsNotModule(el)) {
return true
var cT = getCurrentTransform()
evt.preventDefault()
evt.stopPropagation()
if (evt.deltaY > 0) {
var scale = 1.05 * cT.s
} else {
} else {
var scale = 0.95 * cT.s
return false
}
}
var tx = cT.tx + (evt.pageX - cT.ox) * (1 - 1 / cT.s)
}
var ty = cT.ty + (evt.pageY - cT.oy) * (1 - 1 / cT.s)
 
onwheel = function(evt) {
 
var el = document.elementFromPoint(evt.pageX, evt.pageY)
 
if (elementIsNotModule(el)) {
 
var cT = getCurrentTransform()
 
evt.preventDefault()
 
evt.stopPropagation()
 
if (evt.deltaY > 0) {
 
var scale = 1.05 * cT.s
 
} else {
 
var scale = 0.95 * cT.s
 
}
 
var tx = cT.tx + (evt.pageX - cT.ox) * (1 - 1 / cT.s)
 
var ty = cT.ty + (evt.pageY - cT.oy) * (1 - 1 / cT.s)
// body
// body
document.body.style.transform = `scale(${scale}) translate(${tx}px,${ty}px)`
document.body.style.transform = `scale(${scale}) translate(${tx}px,${ty}px)`
document.body.style.transformOrigin = `${evt.pageX}px ${evt.pageY}px`
document.body.style.transformOrigin = `${evt.pageX}px ${evt.pageY}px`
// opposite for nav
// opposite for nav
nav.style.transformOrigin = `${evt.pageX}px ${evt.pageY}px`
nav.style.transformOrigin = `${evt.pageX}px ${evt.pageY}px`
nav.style.transform = `scale(${1/scale}) translate(${-tx*scale}px,${-ty*scale}px)`
nav.style.transform = `scale(${1/scale}) translate(${-tx*scale}px,${-ty*scale}px)`
 
}
}
}
}
onmousedown = function(evt) {
onmousedown = function(evt) {
var qr = document.querySelector(':focus')
var qr = document.querySelector(':focus')
if (qr) {
if (qr) {
qr.blur()
qr.blur()
 
}
 
var el = document.elementFromPoint(evt.pageX, evt.pageY)
 
if (elementIsNotModule(el)) {
 
evt.preventDefault()
 
evt.stopPropagation()
 
window.addEventListener('mousemove', mouseMoveDragListener)
 
window.addEventListener('mouseup', mouseUpDragListener)
 
}
 
// removes any popup descriptions for list items in Module Menu
 
rmDescription()
}
}
var el = document.elementFromPoint(evt.pageX, evt.pageY)
if (elementIsNotModule(el)) {
function mouseMoveDragListener(evt) {
evt.preventDefault()
evt.preventDefault()
evt.stopPropagation()
evt.stopPropagation()
window.addEventListener('mousemove', mouseMoveDragListener)
var cT = getCurrentTransform()
window.addEventListener('mouseup', mouseUpDragListener)
var dx = evt.movementX
 
var dy = evt.movementY
 
var tx = cT.tx + dx / cT.s
 
var ty = cT.ty + dy / cT.s
 
 
// for body
 
document.body.style.transform = `scale(${cT.s}) translate(${tx}px,${ty}px)`
 
 
// opposite for nav
 
nav.style.transform = `scale(${1/cT.s}) translate(${-tx*cT.s}px,${-ty*cT.s}px)`
}
}
}
function mouseUpDragListener(evt) {
function mouseMoveDragListener(evt) {
window.removeEventListener('mousemove', mouseMoveDragListener)
evt.preventDefault()
window.removeEventListener('mouseup', mouseUpDragListener)
evt.stopPropagation()
}
var cT = getCurrentTransform()
var dx = evt.movementX
// get json menu item and render
var dy = evt.movementY
// and ask for module at /obj/key
var tx = cT.tx + dx / cT.s
oncontextmenu = function(evt) {
var ty = cT.ty + dy / cT.s
console.log(evt.target)
if (evt.target.className == 'modname') {
// for body
var modRep = program.modules[evt.target.innerHTML]
document.body.style.transform = `scale(${cT.s}) translate(${tx}px,${ty}px)`
if (modRep) {
writeModuleOptionMenu(modRep)
// opposite for nav
}
nav.style.transform = `scale(${1/cT.s}) translate(${-tx*cT.s}px,${-ty*cT.s}px)`
}
function mouseUpDragListener(evt) {
window.removeEventListener('mousemove', mouseMoveDragListener)
window.removeEventListener('mouseup', mouseUpDragListener)
}
// get json menu item and render
// and ask for module at /obj/key
oncontextmenu = function(evt) {
console.log(evt.target)
if (evt.target.className == 'modname') {
var modRep = program.modules[evt.target.innerHTML]
if (modRep) {
writeModuleOptionMenu(modRep)
}
} else {
if (sckt) {
socketSend('get module menu', '')
} else {
} else {
// socket brkn, reload page
if (sckt) {
location.reload()
socketSend('get module menu', '')
 
} else {
 
// socket brkn, reload page
 
location.reload()
 
}
 
// prevents event bubbling
}
}
// prevents event bubbling
return false
}
}
return false
}
onmousemove = function(evt) {
onmousemove = function(evt) {
var cT = getCurrentTransform()
var cT = getCurrentTransform()
lastPos.x = cT.ox - cT.tx + (evt.pageX - cT.ox) / cT.s
lastPos.x = cT.ox - cT.tx + (evt.pageX - cT.ox) / cT.s
lastPos.y = cT.oy - cT.ty + (evt.pageY - cT.oy) / cT.s
lastPos.y = cT.oy - cT.ty + (evt.pageY - cT.oy) / cT.s
}
document.onkeydown = function(evt) {
switch (evt.key) {
case 'Escape':
location.reload()
break
case 's':
// get path ?
var path = prompt("path? starting at atkapi/programs/")
socketSend('save program', path)
break
case 'l':
socketSend('get program menu', '')
break
case 'm':
socketSend('get module menu', '')
break
default:
break
}
}
}
document.onkeydown = function(evt) {
function writeModuleOptionMenu(modRep) {
switch (evt.key) {
var menuDom = document.createElement('div')
case 'Escape':
menuDom.id = 'perModuleMenu'
location.reload()
menuDom.style.left = 10 + modRep.ui.domElem.offsetLeft + modRep.ui.domElem.offsetWidth + 'px'
break
menuDom.style.top = modRep.ui.domElem.offsetTop + 'px'
case 's':
// future: rm all inputs, rm all outputs, rename, open (heirarchy)
// get path ?
var opts = ['delete', 'copy']
var path = prompt("path? starting at atkapi/programs/")
for (i in opts) {
socketSend('save program', path)
var li = document.createElement('li')
break
li.innerHTML = opts[i]
case 'l':
li.id = opts[i]
socketSend('get program menu', '')
if (opts[i] == 'delete') {
break
li.addEventListener('click', function(evt) {
case 'm':
var data = {
socketSend('get module menu', '')
id: modRep.description.id
break
}
default:
socketSend('remove module', data)
break
wrapper.removeChild(document.getElementById('perModuleMenu'))
}
})
}
} else if (opts[i] == 'copy') {
li.addEventListener('click', function(evt) {
function writeModuleOptionMenu(modRep) {
var data = modRep.description.path
var menuDom = document.createElement('div')
socketSend('put module', data)
menuDom.id = 'perModuleMenu'
wrapper.removeChild(document.getElementById('perModuleMenu'))
menuDom.style.left = 10 + modRep.ui.domElem.offsetLeft + modRep.ui.domElem.offsetWidth + 'px'
})
menuDom.style.top = modRep.ui.domElem.offsetTop + 'px'
 
// future: rm all inputs, rm all outputs, rename, open (heirarchy)
 
var opts = ['delete', 'copy']
 
for (i in opts) {
 
var li = document.createElement('li')
 
li.innerHTML = opts[i]
 
li.id = opts[i]
 
if (opts[i] == 'delete') {
 
li.addEventListener('click', function(evt) {
 
var data = {
 
id: modRep.description.id
 
}
 
socketSend('remove module', data)
 
wrapper.removeChild(document.getElementById('perModuleMenu'))
 
})
 
} else if (opts[i] == 'copy') {
 
li.addEventListener('click', function(evt) {
 
var data = modRep.description.path
 
socketSend('put module', data)
 
wrapper.removeChild(document.getElementById('perModuleMenu'))
 
})
 
}
 
menuDom.appendChild(li)
}
}
menuDom.appendChild(li)
wrapper.append(menuDom)
 
 
function rmListener(evt) {
 
var findMenu = document.getElementById('perModuleMenu')
 
if (findMenu != null && findMenu.id == 'perModuleMenu') {
 
wrapper.removeChild(findMenu)
 
}
 
evt.target.removeEventListener(evt.type, arguments.callee)
 
}
 
 
document.addEventListener('click', rmListener)
}
}
wrapper.append(menuDom)
function rmListener(evt) {
var findMenu = document.getElementById('perModuleMenu')
// return ul element with name and alt and link?
if (findMenu != null && findMenu.id == 'perModuleMenu') {
// TODO: not properly a tree, see note @ reciprocal fn in views.js
wrapper.removeChild(findMenu)
function heapSendsModuleMenu(tree) {
 
var menuDom = document.createElement('div')
 
menuDom.id = 'moduleMenu'
 
menuDom.style.left = lastPos.x + 'px'
 
menuDom.style.top = lastPos.y + 'px'
 
var title = document.createElement('div')
 
title.className = 'title'
 
title.innerHTML = 'module menu'
 
menuDom.appendChild(title)
 
for (key in tree) {
 
var ul = document.createElement('ul')
 
var header = document.createElement('h4')
 
//ul.innerHTML = key.toString()
 
// create header for ul
 
header.innerHTML = key.toString()
 
ul.append(header)
 
for (subkey in tree[key]) {
 
var li = document.createElement('li')
 
var path = tree[key][subkey].path
 
li.innerHTML = subkey.toString()
 
li.id = path
 
li.addEventListener('mouseover', function(evt){
 
rmDescription()//
 
writeModuleDescription(evt)//
 
})
 
//////////////////////////////////////////////////////////
 
li.addEventListener('click', function(evt) {
 
var data = this.id
 
socketSend('put module', data)
 
wrapper.removeChild(document.getElementById('moduleMenu'))
 
})
 
ul.appendChild(li)
 
}
 
menuDom.appendChild(ul)
 
}
 
wrapper.append(menuDom)
 
 
function rmListener(evt) {
 
var findMenu = document.getElementById('moduleMenu')
 
if (findMenu !== null && findMenu.id == 'moduleMenu') {
 
wrapper.removeChild(findMenu)
 
}
 
evt.target.removeEventListener(evt.type, arguments.callee)
}
}
evt.target.removeEventListener(evt.type, arguments.callee)
 
document.addEventListener('click', rmListener)
}
}
document.addEventListener('click', rmListener)
function heapSendsProgramMenu(tree) {
}
var menuDom = document.createElement('div')
menuDom.id = 'programMenu'
// return ul element with name and alt and link?
menuDom.style.left = lastPos.x + 'px'
// TODO: not properly a tree, see note @ reciprocal fn in views.js
menuDom.style.top = lastPos.y + 'px'
function heapSendsModuleMenu(tree) {
for (key in tree) {
var menuDom = document.createElement('div')
menuDom.id = 'moduleMenu'
menuDom.style.left = lastPos.x + 'px'
menuDom.style.top = lastPos.y + 'px'
var title = document.createElement('div')
title.className = 'title'
title.innerHTML = 'module menu'
menuDom.appendChild(title)
for (key in tree) {
var ul = document.createElement('ul')
ul.innerHTML = key.toString()
for (subkey in tree[key]) {
var li = document.createElement('li')
var li = document.createElement('li')
var path = tree[key][subkey].path
var path = tree[key].path
li.innerHTML = subkey.toString()
li.innerHTML = key.toString()
li.id = path
li.id = path
li.addEventListener('click', function(evt) {
li.addEventListener('click', function(evt) {
var data = this.id
var data = this.id
socketSend('put module', data)
socketSend('load program', data)
wrapper.removeChild(document.getElementById('moduleMenu'))
wrapper.removeChild(document.getElementById('programMenu'))
})
})
ul.appendChild(li)
menuDom.appendChild(li)
}
}
menuDom.appendChild(ul)
wrapper.append(menuDom)
}
wrapper.append(menuDom)
function rmListener(evt) {
function rmListener(evt) {
var findMenu = document.getElementById('moduleMenu')
var findMenu = document.getElementById('programMenu')
if (findMenu !== null && findMenu.id == 'moduleMenu') {
if (findMenu !== null && findMenu.id == 'programMenu') {
wrapper.removeChild(findMenu)
wrapper.removeChild(findMenu)
 
}
 
// rm this listner...
 
evt.target.removeEventListener(evt.type, arguments.callee)
}
}
evt.target.removeEventListener(evt.type, arguments.callee)
}
document.addEventListener('click', rmListener)
document.addEventListener('click', rmListener)
}
function heapSendsProgramMenu(tree) {
var menuDom = document.createElement('div')
menuDom.id = 'programMenu'
menuDom.style.left = lastPos.x + 'px'
menuDom.style.top = lastPos.y + 'px'
for (key in tree) {
var li = document.createElement('li')
var path = tree[key].path
li.innerHTML = key.toString()
li.id = path
li.addEventListener('click', function(evt) {
var data = this.id
socketSend('load program', data)
wrapper.removeChild(document.getElementById('programMenu'))
})
menuDom.appendChild(li)
}
}
wrapper.append(menuDom)
function rmListener(evt) {
var findMenu = document.getElementById('programMenu')
// Paloma adds
if (findMenu !== null && findMenu.id == 'programMenu') {
wrapper.removeChild(findMenu)
// module descriptions
 
const moduleDescriptionsObj =
 
{
 
and : 'this is the description for and',
 
atkbreadboard: 'this is the description for atkbreadboard',
 
atkseriallink: 'this is the description for atkseriallink',
 
atkstepper: 'this is the description for akstepper',
 
webcam : 'this is description for webcam',
 
planner: 'this is the description for planner',
 
rawmove: 'this is the description for rawmove',
 
gcode: 'this is the descriprion for gcode'
}
}
// rm this listner...
evt.target.removeEventListener(evt.type, arguments.callee)
function writeModuleDescription(evt) {
 
let liRect = evt.target.getBoundingClientRect();
 
let menuDes = document.createElement('div')
 
menuDes.id = 'moduleDescription'
 
menuDes.style.left = 255 + liRect.left + 'px'
 
menuDes.style.top = liRect.top - 18 + 'px'
 
let parentEl = evt.target.parentElement
 
let headerKey = parentEl.firstChild.innerHTML
 
menuDes.innerHTML = moduleDescriptionsObj[evt.target.innerHTML]
 
wrapper.append(menuDes)
}
}
document.addEventListener('click', rmListener)
function rmDescription() {
}
let modDes = document.getElementById('moduleDescription')
\ No newline at end of file
if (modDes != null) {
 
wrapper.removeChild(modDes)
 
}
 
}
 
\ No newline at end of file
Loading