@@ -1,4 +1,5 @@ | |||
/** | |||
/** Modified from original Node-Red source, for audio system visualization | |||
* vim: set ts=4: | |||
* Copyright 2014 IBM Corp. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
@@ -15,65 +16,65 @@ | |||
**/ | |||
RED.comms = (function() { | |||
var errornotification = null; | |||
var subscriptions = {}; | |||
var ws; | |||
function connectWS() { | |||
var path = location.hostname+":"+location.port+document.location.pathname; | |||
path = path+(path.slice(-1) == "/"?"":"/")+"comms"; | |||
path = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path; | |||
ws = new WebSocket(path); | |||
ws.onopen = function() { | |||
if (errornotification) { | |||
errornotification.close(); | |||
errornotification = null; | |||
} | |||
for (var t in subscriptions) { | |||
if (subscriptions.hasOwnProperty(t)) { | |||
ws.send(JSON.stringify({subscribe:t})); | |||
} | |||
} | |||
} | |||
ws.onmessage = function(event) { | |||
var msg = JSON.parse(event.data); | |||
if (msg.topic) { | |||
for (var t in subscriptions) { | |||
if (subscriptions.hasOwnProperty(t)) { | |||
var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$"); | |||
if (re.test(msg.topic)) { | |||
var subscribers = subscriptions[t]; | |||
if (subscribers) { | |||
for (var i=0;i<subscribers.length;i++) { | |||
subscribers[i](msg.topic,msg.data); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
}; | |||
ws.onclose = function() { | |||
if (errornotification == null) { | |||
errornotification = RED.notify("<b>Error</b>: Lost connection to server","error",true); | |||
} | |||
setTimeout(connectWS,1000); | |||
} | |||
} | |||
function subscribe(topic,callback) { | |||
if (subscriptions[topic] == null) { | |||
subscriptions[topic] = []; | |||
} | |||
subscriptions[topic].push(callback); | |||
if (ws && ws.readyState == 1) { | |||
ws.send(JSON.stringify({subscribe:topic})); | |||
} | |||
} | |||
return { | |||
connect: connectWS, | |||
subscribe: subscribe | |||
} | |||
var errornotification = null; | |||
var subscriptions = {}; | |||
var ws; | |||
function connectWS() { | |||
var path = location.hostname+":"+location.port+document.location.pathname; | |||
path = path+(path.slice(-1) == "/"?"":"/")+"comms"; | |||
path = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path; | |||
ws = new WebSocket(path); | |||
ws.onopen = function() { | |||
if (errornotification) { | |||
errornotification.close(); | |||
errornotification = null; | |||
} | |||
for (var t in subscriptions) { | |||
if (subscriptions.hasOwnProperty(t)) { | |||
ws.send(JSON.stringify({subscribe:t})); | |||
} | |||
} | |||
} | |||
ws.onmessage = function(event) { | |||
var msg = JSON.parse(event.data); | |||
if (msg.topic) { | |||
for (var t in subscriptions) { | |||
if (subscriptions.hasOwnProperty(t)) { | |||
var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$"); | |||
if (re.test(msg.topic)) { | |||
var subscribers = subscriptions[t]; | |||
if (subscribers) { | |||
for (var i=0;i<subscribers.length;i++) { | |||
subscribers[i](msg.topic,msg.data); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
}; | |||
ws.onclose = function() { | |||
if (errornotification == null) { | |||
errornotification = RED.notify("<b>Error</b>: Lost connection to server","error",true); | |||
} | |||
setTimeout(connectWS,1000); | |||
} | |||
} | |||
function subscribe(topic,callback) { | |||
if (subscriptions[topic] == null) { | |||
subscriptions[topic] = []; | |||
} | |||
subscriptions[topic].push(callback); | |||
if (ws && ws.readyState == 1) { | |||
ws.send(JSON.stringify({subscribe:topic})); | |||
} | |||
} | |||
return { | |||
connect: connectWS, | |||
subscribe: subscribe | |||
} | |||
})(); |
@@ -1,4 +1,5 @@ | |||
/** | |||
/** Modified from original Node-Red source, for audio system visualization | |||
* vim: set ts=4: | |||
* Copyright 2013 IBM Corp. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
@@ -14,72 +15,72 @@ | |||
* limitations under the License. | |||
**/ | |||
RED.history = (function() { | |||
var undo_history = []; | |||
return { | |||
//TODO: this function is a placeholder until there is a 'save' event that can be listened to | |||
markAllDirty: function() { | |||
for (var i=0;i<undo_history.length;i++) { | |||
undo_history[i].dirty = true; | |||
} | |||
}, | |||
depth: function() { | |||
return undo_history.length; | |||
}, | |||
push: function(ev) { | |||
undo_history.push(ev); | |||
}, | |||
pop: function() { | |||
var ev = undo_history.pop(); | |||
var i; | |||
if (ev) { | |||
if (ev.t == 'add') { | |||
for (i=0;i<ev.nodes.length;i++) { | |||
RED.nodes.remove(ev.nodes[i]); | |||
} | |||
for (i=0;i<ev.links.length;i++) { | |||
RED.nodes.removeLink(ev.links[i]); | |||
} | |||
for (i=0;i<ev.workspaces.length;i++) { | |||
RED.nodes.removeWorkspace(ev.workspaces[i].id); | |||
RED.view.removeWorkspace(ev.workspaces[i]); | |||
} | |||
} else if (ev.t == "delete") { | |||
for (i=0;i<ev.workspaces.length;i++) { | |||
RED.nodes.addWorkspace(ev.workspaces[i]); | |||
RED.view.addWorkspace(ev.workspaces[i]); | |||
} | |||
for (i=0;i<ev.nodes.length;i++) { | |||
RED.nodes.add(ev.nodes[i]); | |||
} | |||
for (i=0;i<ev.links.length;i++) { | |||
RED.nodes.addLink(ev.links[i]); | |||
} | |||
} else if (ev.t == "move") { | |||
for (i=0;i<ev.nodes.length;i++) { | |||
var n = ev.nodes[i]; | |||
n.n.x = n.ox; | |||
n.n.y = n.oy; | |||
n.n.dirty = true; | |||
} | |||
} else if (ev.t == "edit") { | |||
for (i in ev.changes) { | |||
if (ev.changes.hasOwnProperty(i)) { | |||
ev.node[i] = ev.changes[i]; | |||
} | |||
} | |||
RED.editor.updateNodeProperties(ev.node); | |||
for (i=0;i<ev.links.length;i++) { | |||
RED.nodes.addLink(ev.links[i]); | |||
} | |||
RED.editor.validateNode(ev.node); | |||
ev.node.dirty = true; | |||
ev.node.changed = ev.changed; | |||
} | |||
RED.view.dirty(ev.dirty); | |||
RED.view.redraw(); | |||
} | |||
} | |||
} | |||
var undo_history = []; | |||
return { | |||
//TODO: this function is a placeholder until there is a 'save' event that can be listened to | |||
markAllDirty: function() { | |||
for (var i=0;i<undo_history.length;i++) { | |||
undo_history[i].dirty = true; | |||
} | |||
}, | |||
depth: function() { | |||
return undo_history.length; | |||
}, | |||
push: function(ev) { | |||
undo_history.push(ev); | |||
}, | |||
pop: function() { | |||
var ev = undo_history.pop(); | |||
var i; | |||
if (ev) { | |||
if (ev.t == 'add') { | |||
for (i=0;i<ev.nodes.length;i++) { | |||
RED.nodes.remove(ev.nodes[i]); | |||
} | |||
for (i=0;i<ev.links.length;i++) { | |||
RED.nodes.removeLink(ev.links[i]); | |||
} | |||
for (i=0;i<ev.workspaces.length;i++) { | |||
RED.nodes.removeWorkspace(ev.workspaces[i].id); | |||
RED.view.removeWorkspace(ev.workspaces[i]); | |||
} | |||
} else if (ev.t == "delete") { | |||
for (i=0;i<ev.workspaces.length;i++) { | |||
RED.nodes.addWorkspace(ev.workspaces[i]); | |||
RED.view.addWorkspace(ev.workspaces[i]); | |||
} | |||
for (i=0;i<ev.nodes.length;i++) { | |||
RED.nodes.add(ev.nodes[i]); | |||
} | |||
for (i=0;i<ev.links.length;i++) { | |||
RED.nodes.addLink(ev.links[i]); | |||
} | |||
} else if (ev.t == "move") { | |||
for (i=0;i<ev.nodes.length;i++) { | |||
var n = ev.nodes[i]; | |||
n.n.x = n.ox; | |||
n.n.y = n.oy; | |||
n.n.dirty = true; | |||
} | |||
} else if (ev.t == "edit") { | |||
for (i in ev.changes) { | |||
if (ev.changes.hasOwnProperty(i)) { | |||
ev.node[i] = ev.changes[i]; | |||
} | |||
} | |||
RED.editor.updateNodeProperties(ev.node); | |||
for (i=0;i<ev.links.length;i++) { | |||
RED.nodes.addLink(ev.links[i]); | |||
} | |||
RED.editor.validateNode(ev.node); | |||
ev.node.dirty = true; | |||
ev.node.changed = ev.changed; | |||
} | |||
RED.view.dirty(ev.dirty); | |||
RED.view.redraw(); | |||
} | |||
} | |||
} | |||
})(); |
@@ -1,4 +1,5 @@ | |||
/** | |||
/** Modified from original Node-Red source, for audio system visualization | |||
* vim: set ts=4: | |||
* Copyright 2013 IBM Corp. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
@@ -15,233 +16,234 @@ | |||
**/ | |||
var RED = (function() { | |||
$('#btn-keyboard-shortcuts').click(function(){showHelp();}); | |||
function hideDropTarget() { | |||
$("#dropTarget").hide(); | |||
RED.keyboard.remove(/* ESCAPE */ 27); | |||
} | |||
$('#chart').on("dragenter",function(event) { | |||
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) { | |||
$("#dropTarget").css({display:'table'}); | |||
RED.keyboard.add(/* ESCAPE */ 27,hideDropTarget); | |||
} | |||
}); | |||
$('#dropTarget').on("dragover",function(event) { | |||
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) { | |||
event.preventDefault(); | |||
} | |||
}) | |||
.on("dragleave",function(event) { | |||
hideDropTarget(); | |||
}) | |||
.on("drop",function(event) { | |||
var data = event.originalEvent.dataTransfer.getData("text/plain"); | |||
hideDropTarget(); | |||
RED.view.importNodes(data); | |||
event.preventDefault(); | |||
}); | |||
function save(force) { | |||
if (RED.view.dirty()) { | |||
if (!force) { | |||
var invalid = false; | |||
var unknownNodes = []; | |||
RED.nodes.eachNode(function(node) { | |||
invalid = invalid || !node.valid; | |||
if (node.type === "unknown") { | |||
if (unknownNodes.indexOf(node.name) == -1) { | |||
unknownNodes.push(node.name); | |||
} | |||
invalid = true; | |||
} | |||
}); | |||
if (invalid) { | |||
if (unknownNodes.length > 0) { | |||
$( "#node-dialog-confirm-deploy-config" ).hide(); | |||
$( "#node-dialog-confirm-deploy-unknown" ).show(); | |||
var list = "<li>"+unknownNodes.join("</li><li>")+"</li>"; | |||
$( "#node-dialog-confirm-deploy-unknown-list" ).html(list); | |||
} else { | |||
$( "#node-dialog-confirm-deploy-config" ).show(); | |||
$( "#node-dialog-confirm-deploy-unknown" ).hide(); | |||
} | |||
$( "#node-dialog-confirm-deploy" ).dialog( "open" ); | |||
return; | |||
} | |||
} | |||
var nns = RED.nodes.createCompleteNodeSet(); | |||
$("#btn-icn-deploy").removeClass('icon-upload'); | |||
$("#btn-icn-deploy").addClass('spinner'); | |||
RED.view.dirty(false); | |||
console.log(JSON.stringify(nns)); | |||
$.ajax({ | |||
url:"flows", | |||
type: "POST", | |||
data: JSON.stringify(nns), | |||
contentType: "application/json; charset=utf-8" | |||
}).done(function(data,textStatus,xhr) { | |||
RED.notify("Successfully deployed","success"); | |||
RED.nodes.eachNode(function(node) { | |||
if (node.changed) { | |||
node.dirty = true; | |||
node.changed = false; | |||
} | |||
if(node.credentials) { | |||
delete node.credentials; | |||
} | |||
}); | |||
RED.nodes.eachConfig(function (confNode) { | |||
if (confNode.credentials) { | |||
delete confNode.credentials; | |||
} | |||
}); | |||
// Once deployed, cannot undo back to a clean state | |||
RED.history.markAllDirty(); | |||
RED.view.redraw(); | |||
}).fail(function(xhr,textStatus,err) { | |||
RED.view.dirty(true); | |||
if (xhr.responseText) { | |||
RED.notify("<strong>Error</strong>: "+xhr.responseText,"error"); | |||
} else { | |||
RED.notify("<strong>Error</strong>: no response from server","error"); | |||
} | |||
}).always(function() { | |||
$("#btn-icn-deploy").removeClass('spinner'); | |||
$("#btn-icn-deploy").addClass('icon-upload'); | |||
}); | |||
} | |||
} | |||
$('#btn-deploy').click(function() { save(); }); | |||
$( "#node-dialog-confirm-deploy" ).dialog({ | |||
title: "Confirm deploy", | |||
modal: true, | |||
autoOpen: false, | |||
width: 530, | |||
height: 230, | |||
buttons: [ | |||
{ | |||
text: "Confirm deploy", | |||
click: function() { | |||
save(true); | |||
$( this ).dialog( "close" ); | |||
} | |||
}, | |||
{ | |||
text: "Cancel", | |||
click: function() { | |||
$( this ).dialog( "close" ); | |||
} | |||
} | |||
] | |||
}); | |||
function loadSettings() { | |||
$('#btn-keyboard-shortcuts').click(function(){showHelp();}); | |||
function hideDropTarget() { | |||
$("#dropTarget").hide(); | |||
RED.keyboard.remove(/* ESCAPE */ 27); | |||
} | |||
$('#chart').on("dragenter",function(event) { | |||
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) { | |||
$("#dropTarget").css({display:'table'}); | |||
RED.keyboard.add(/* ESCAPE */ 27,hideDropTarget); | |||
} | |||
}); | |||
$('#dropTarget').on("dragover",function(event) { | |||
if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) { | |||
event.preventDefault(); | |||
} | |||
}) | |||
.on("dragleave",function(event) { | |||
hideDropTarget(); | |||
}) | |||
.on("drop",function(event) { | |||
var data = event.originalEvent.dataTransfer.getData("text/plain"); | |||
hideDropTarget(); | |||
RED.view.importNodes(data); | |||
event.preventDefault(); | |||
}); | |||
function save(force) { | |||
if (RED.view.dirty()) { | |||
if (!force) { | |||
var invalid = false; | |||
var unknownNodes = []; | |||
RED.nodes.eachNode(function(node) { | |||
invalid = invalid || !node.valid; | |||
if (node.type === "unknown") { | |||
if (unknownNodes.indexOf(node.name) == -1) { | |||
unknownNodes.push(node.name); | |||
} | |||
invalid = true; | |||
} | |||
}); | |||
if (invalid) { | |||
if (unknownNodes.length > 0) { | |||
$( "#node-dialog-confirm-deploy-config" ).hide(); | |||
$( "#node-dialog-confirm-deploy-unknown" ).show(); | |||
var list = "<li>"+unknownNodes.join("</li><li>")+"</li>"; | |||
$( "#node-dialog-confirm-deploy-unknown-list" ).html(list); | |||
} else { | |||
$( "#node-dialog-confirm-deploy-config" ).show(); | |||
$( "#node-dialog-confirm-deploy-unknown" ).hide(); | |||
} | |||
$( "#node-dialog-confirm-deploy" ).dialog( "open" ); | |||
return; | |||
} | |||
} | |||
var nns = RED.nodes.createCompleteNodeSet(); | |||
$("#btn-icn-deploy").removeClass('icon-upload'); | |||
$("#btn-icn-deploy").addClass('spinner'); | |||
RED.view.dirty(false); | |||
console.log(JSON.stringify(nns)); | |||
$.ajax({ | |||
url:"flows", | |||
type: "POST", | |||
data: JSON.stringify(nns), | |||
contentType: "application/json; charset=utf-8" | |||
}).done(function(data,textStatus,xhr) { | |||
RED.notify("Successfully deployed","success"); | |||
RED.nodes.eachNode(function(node) { | |||
if (node.changed) { | |||
node.dirty = true; | |||
node.changed = false; | |||
} | |||
if(node.credentials) { | |||
delete node.credentials; | |||
} | |||
}); | |||
RED.nodes.eachConfig(function (confNode) { | |||
if (confNode.credentials) { | |||
delete confNode.credentials; | |||
} | |||
}); | |||
// Once deployed, cannot undo back to a clean state | |||
RED.history.markAllDirty(); | |||
RED.view.redraw(); | |||
}).fail(function(xhr,textStatus,err) { | |||
RED.view.dirty(true); | |||
if (xhr.responseText) { | |||
RED.notify("<strong>Error</strong>: "+xhr.responseText,"error"); | |||
} else { | |||
RED.notify("<strong>Error</strong>: no response from server","error"); | |||
} | |||
}).always(function() { | |||
$("#btn-icn-deploy").removeClass('spinner'); | |||
$("#btn-icn-deploy").addClass('icon-upload'); | |||
}); | |||
} | |||
} | |||
$('#btn-deploy').click(function() { save(); }); | |||
$( "#node-dialog-confirm-deploy" ).dialog({ | |||
title: "Confirm deploy", | |||
modal: true, | |||
autoOpen: false, | |||
width: 530, | |||
height: 230, | |||
buttons: [ | |||
{ | |||
text: "Confirm deploy", | |||
click: function() { | |||
save(true); | |||
$( this ).dialog( "close" ); | |||
} | |||
}, | |||
{ | |||
text: "Cancel", | |||
click: function() { | |||
$( this ).dialog( "close" ); | |||
} | |||
} | |||
] | |||
}); | |||
function loadSettings() { | |||
/* | |||
$.get('settings', function(data) { | |||
RED.settings = data; | |||
console.log("Node-RED: "+data.version); | |||
loadNodes(); | |||
}); | |||
$.get('settings', function(data) { | |||
RED.settings = data; | |||
console.log("Node-RED: "+data.version); | |||
loadNodes(); | |||
}); | |||
*/ | |||
loadNodes(); | |||
} | |||
function loadNodes() { | |||
loadNodes(); | |||
} | |||
function loadNodes() { | |||
console.log("loadNodes"); | |||
$.get('list.html', function(data) { | |||
console.log("loadNodes complete"); | |||
$("body").append(data); | |||
$(".palette-spinner").hide(); | |||
$(".palette-scroll").show(); | |||
$("#palette-search").show(); | |||
//loadFlows(); | |||
}, "html"); | |||
} | |||
function loadFlows() { | |||
$.getJSON("flows",function(nodes) { | |||
RED.nodes.import(nodes); | |||
RED.view.dirty(false); | |||
RED.view.redraw(); | |||
RED.comms.subscribe("status/#",function(topic,msg) { | |||
var parts = topic.split("/"); | |||
var node = RED.nodes.node(parts[1]); | |||
if (node) { | |||
node.status = msg; | |||
if (statusEnabled) { | |||
node.dirty = true; | |||
RED.view.redraw(); | |||
} | |||
} | |||
}); | |||
RED.comms.subscribe("node/#",function(topic,msg) { | |||
var i; | |||
if (topic == "node/added") { | |||
for (i=0;i<msg.length;i++) { | |||
var m = msg[i]; | |||
var id = m.id; | |||
$.get('nodes/'+id, function(data) { | |||
$("body").append(data); | |||
var typeList = "<ul><li>"+m.types.join("</li><li>")+"</li></ul>"; | |||
RED.notify("Node"+(m.types.length!=1 ? "s":"")+" added to palette:"+typeList,"success"); | |||
}); | |||
} | |||
} else if (topic == "node/removed") { | |||
if (msg.types) { | |||
for (i=0;i<msg.types.length;i++) { | |||
RED.palette.remove(msg.types[i]); | |||
} | |||
var typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>"; | |||
RED.notify("Node"+(msg.types.length!=1 ? "s":"")+" removed from palette:"+typeList,"success"); | |||
} | |||
} | |||
}); | |||
}); | |||
} | |||
$('#btn-node-status').click(function() {toggleStatus();}); | |||
var statusEnabled = false; | |||
function toggleStatus() { | |||
var btnStatus = $("#btn-node-status"); | |||
statusEnabled = btnStatus.toggleClass("active").hasClass("active"); | |||
RED.view.status(statusEnabled); | |||
} | |||
function showHelp() { | |||
var dialog = $('#node-help'); | |||
//$("#node-help").draggable({ | |||
// handle: ".modal-header" | |||
//}); | |||
dialog.on('show',function() { | |||
RED.keyboard.disable(); | |||
}); | |||
dialog.on('hidden',function() { | |||
RED.keyboard.enable(); | |||
}); | |||
dialog.modal(); | |||
} | |||
$(function() { | |||
RED.keyboard.add(/* ? */ 191,{shift:true},function(){showHelp();d3.event.preventDefault();}); | |||
loadSettings(); | |||
RED.comms.connect(); | |||
}); | |||
return { | |||
}; | |||
$.get('list.html', function(data) { | |||
console.log("loadNodes complete"); | |||
$("body").append(data); | |||
$(".palette-spinner").hide(); | |||
$(".palette-scroll").show(); | |||
$("#palette-search").show(); | |||
//loadFlows(); | |||
}, "html"); | |||
} | |||
function loadFlows() { | |||
$.getJSON("flows",function(nodes) { | |||
RED.nodes.import(nodes); | |||
RED.view.dirty(false); | |||
RED.view.redraw(); | |||
RED.comms.subscribe("status/#",function(topic,msg) { | |||
var parts = topic.split("/"); | |||
var node = RED.nodes.node(parts[1]); | |||
if (node) { | |||
node.status = msg; | |||
if (statusEnabled) { | |||
node.dirty = true; | |||
RED.view.redraw(); | |||
} | |||
} | |||
}); | |||
RED.comms.subscribe("node/#",function(topic,msg) { | |||
var i; | |||
if (topic == "node/added") { | |||
for (i=0;i<msg.length;i++) { | |||
var m = msg[i]; | |||
var id = m.id; | |||
$.get('nodes/'+id, function(data) { | |||
$("body").append(data); | |||
var typeList = "<ul><li>"+m.types.join("</li><li>")+"</li></ul>"; | |||
RED.notify("Node"+(m.types.length!=1 ? "s":"")+" added to palette:"+typeList,"success"); | |||
}); | |||
} | |||
} else if (topic == "node/removed") { | |||
if (msg.types) { | |||
for (i=0;i<msg.types.length;i++) { | |||
RED.palette.remove(msg.types[i]); | |||
} | |||
var typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>"; | |||
RED.notify("Node"+(msg.types.length!=1 ? "s":"")+" removed from palette:"+typeList,"success"); | |||
} | |||
} | |||
}); | |||
}); | |||
} | |||
$('#btn-node-status').click(function() {toggleStatus();}); | |||
var statusEnabled = false; | |||
function toggleStatus() { | |||
var btnStatus = $("#btn-node-status"); | |||
statusEnabled = btnStatus.toggleClass("active").hasClass("active"); | |||
RED.view.status(statusEnabled); | |||
} | |||
function showHelp() { | |||
var dialog = $('#node-help'); | |||
//$("#node-help").draggable({ | |||
// handle: ".modal-header" | |||
//}); | |||
dialog.on('show',function() { | |||
RED.keyboard.disable(); | |||
}); | |||
dialog.on('hidden',function() { | |||
RED.keyboard.enable(); | |||
}); | |||
dialog.modal(); | |||
} | |||
$(function() { | |||
RED.keyboard.add(/* ? */ 191,{shift:true},function(){showHelp();d3.event.preventDefault();}); | |||
loadSettings(); | |||
RED.comms.connect(); | |||
}); | |||
return { | |||
}; | |||
})(); |
@@ -16,43 +16,43 @@ | |||
**/ | |||
RED.nodes = (function() { | |||
var node_defs = {}; | |||
var nodes = []; | |||
var configNodes = {}; | |||
var links = []; | |||
var defaultWorkspace; | |||
var workspaces = {}; | |||
var node_defs = {}; | |||
var nodes = []; | |||
var configNodes = {}; | |||
var links = []; | |||
var defaultWorkspace; | |||
var workspaces = {}; | |||
function registerType(nt,def) { | |||
node_defs[nt] = def; | |||
// TODO: too tightly coupled into palette UI | |||
RED.palette.add(nt,def); | |||
} | |||
function registerType(nt,def) { | |||
node_defs[nt] = def; | |||
// TODO: too tightly coupled into palette UI | |||
RED.palette.add(nt,def); | |||
} | |||
function getID() { | |||
function getID() { | |||
var str = (1+Math.random()*4294967295).toString(16); | |||
console.log("getID = " + str); | |||
return str; | |||
} | |||
} | |||
function checkID(name) { | |||
var i; | |||
for (i=0;i<nodes.length;i++) { | |||
var i; | |||
for (i=0;i<nodes.length;i++) { | |||
console.log("checkID, nodes[i].id = " + nodes[i].id); | |||
if (nodes[i].id == name) return true; | |||
} | |||
} | |||
/* | |||
for (i in workspaces) { | |||
if (workspaces.hasOwnProperty(i)) { } | |||
} | |||
for (i in configNodes) { | |||
if (configNodes.hasOwnProperty(i)) { } | |||
} | |||
for (i in workspaces) { | |||
if (workspaces.hasOwnProperty(i)) { } | |||
} | |||
for (i in configNodes) { | |||
if (configNodes.hasOwnProperty(i)) { } | |||
} | |||
*/ | |||
return false; | |||
} | |||
function createUniqueCppName(n) { | |||
function createUniqueCppName(n) { | |||
console.log("getUniqueCppName, n.type=" + n.type + ", n._def.shortName=" + n._def.shortName); | |||
var basename = (n._def.shortName) ? n._def.shortName : n.type.replace(/^Analog/, ""); | |||
console.log("getUniqueCppName, using basename=" + basename); | |||
@@ -66,423 +66,423 @@ RED.nodes = (function() { | |||
} | |||
console.log("getUniqueCppName, unique name=" + name); | |||
return name; | |||
} | |||
} | |||
function getType(type) { | |||
return node_defs[type]; | |||
} | |||
function getType(type) { | |||
return node_defs[type]; | |||
} | |||
function addNode(n) { | |||
if (n._def.category == "config") { | |||
configNodes[n.id] = n; | |||
RED.sidebar.config.refresh(); | |||
} else { | |||
n.dirty = true; | |||
nodes.push(n); | |||
var updatedConfigNode = false; | |||
for (var d in n._def.defaults) { | |||
if (n._def.defaults.hasOwnProperty(d)) { | |||
var property = n._def.defaults[d]; | |||
if (property.type) { | |||
var type = getType(property.type) | |||
if (type && type.category == "config") { | |||
var configNode = configNodes[n[d]]; | |||
if (configNode) { | |||
updatedConfigNode = true; | |||
configNode.users.push(n); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
if (updatedConfigNode) { | |||
RED.sidebar.config.refresh(); | |||
} | |||
} | |||
} | |||
function addLink(l) { | |||
links.push(l); | |||
} | |||
function addConfig(c) { | |||
configNodes[c.id] = c; | |||
} | |||
function addNode(n) { | |||
if (n._def.category == "config") { | |||
configNodes[n.id] = n; | |||
RED.sidebar.config.refresh(); | |||
} else { | |||
n.dirty = true; | |||
nodes.push(n); | |||
var updatedConfigNode = false; | |||
for (var d in n._def.defaults) { | |||
if (n._def.defaults.hasOwnProperty(d)) { | |||
var property = n._def.defaults[d]; | |||
if (property.type) { | |||
var type = getType(property.type) | |||
if (type && type.category == "config") { | |||
var configNode = configNodes[n[d]]; | |||
if (configNode) { | |||
updatedConfigNode = true; | |||
configNode.users.push(n); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
if (updatedConfigNode) { | |||
RED.sidebar.config.refresh(); | |||
} | |||
} | |||
} | |||
function addLink(l) { | |||
links.push(l); | |||
} | |||
function addConfig(c) { | |||
configNodes[c.id] = c; | |||
} | |||
function getNode(id) { | |||
if (id in configNodes) { | |||
return configNodes[id]; | |||
} else { | |||
for (var n in nodes) { | |||
if (nodes[n].id == id) { | |||
return nodes[n]; | |||
} | |||
} | |||
} | |||
return null; | |||
} | |||
function getNode(id) { | |||
if (id in configNodes) { | |||
return configNodes[id]; | |||
} else { | |||
for (var n in nodes) { | |||
if (nodes[n].id == id) { | |||
return nodes[n]; | |||
} | |||
} | |||
} | |||
return null; | |||
} | |||
function removeNode(id) { | |||
var removedLinks = []; | |||
if (id in configNodes) { | |||
delete configNodes[id]; | |||
RED.sidebar.config.refresh(); | |||
} else { | |||
var node = getNode(id); | |||
if (node) { | |||
nodes.splice(nodes.indexOf(node),1); | |||
removedLinks = links.filter(function(l) { return (l.source === node) || (l.target === node); }); | |||
removedLinks.map(function(l) {links.splice(links.indexOf(l), 1); }); | |||
} | |||
var updatedConfigNode = false; | |||
for (var d in node._def.defaults) { | |||
if (node._def.defaults.hasOwnProperty(d)) { | |||
var property = node._def.defaults[d]; | |||
if (property.type) { | |||
var type = getType(property.type) | |||
if (type && type.category == "config") { | |||
var configNode = configNodes[node[d]]; | |||
if (configNode) { | |||
updatedConfigNode = true; | |||
var users = configNode.users; | |||
users.splice(users.indexOf(node),1); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
if (updatedConfigNode) { | |||
RED.sidebar.config.refresh(); | |||
} | |||
} | |||
return removedLinks; | |||
} | |||
function removeNode(id) { | |||
var removedLinks = []; | |||
if (id in configNodes) { | |||
delete configNodes[id]; | |||
RED.sidebar.config.refresh(); | |||
} else { | |||
var node = getNode(id); | |||
if (node) { | |||
nodes.splice(nodes.indexOf(node),1); | |||
removedLinks = links.filter(function(l) { return (l.source === node) || (l.target === node); }); | |||
removedLinks.map(function(l) {links.splice(links.indexOf(l), 1); }); | |||
} | |||
var updatedConfigNode = false; | |||
for (var d in node._def.defaults) { | |||
if (node._def.defaults.hasOwnProperty(d)) { | |||
var property = node._def.defaults[d]; | |||
if (property.type) { | |||
var type = getType(property.type) | |||
if (type && type.category == "config") { | |||
var configNode = configNodes[node[d]]; | |||
if (configNode) { | |||
updatedConfigNode = true; | |||
var users = configNode.users; | |||
users.splice(users.indexOf(node),1); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
if (updatedConfigNode) { | |||
RED.sidebar.config.refresh(); | |||
} | |||
} | |||
return removedLinks; | |||
} | |||
function removeLink(l) { | |||
var index = links.indexOf(l); | |||
if (index != -1) { | |||
links.splice(index,1); | |||
} | |||
} | |||
function removeLink(l) { | |||
var index = links.indexOf(l); | |||
if (index != -1) { | |||
links.splice(index,1); | |||
} | |||
} | |||
function refreshValidation() { | |||
for (var n=0;n<nodes.length;n++) { | |||
RED.editor.validateNode(nodes[n]); | |||
} | |||
} | |||
function refreshValidation() { | |||
for (var n=0;n<nodes.length;n++) { | |||
RED.editor.validateNode(nodes[n]); | |||
} | |||
} | |||
function addWorkspace(ws) { | |||
workspaces[ws.id] = ws; | |||
} | |||
function getWorkspace(id) { | |||
return workspaces[id]; | |||
} | |||
function removeWorkspace(id) { | |||
delete workspaces[id]; | |||
var removedNodes = []; | |||
var removedLinks = []; | |||
var n; | |||
for (n=0;n<nodes.length;n++) { | |||
var node = nodes[n]; | |||
if (node.z == id) { | |||
removedNodes.push(node); | |||
} | |||
} | |||
for (n=0;n<removedNodes.length;n++) { | |||
var rmlinks = removeNode(removedNodes[n].id); | |||
removedLinks = removedLinks.concat(rmlinks); | |||
} | |||
return {nodes:removedNodes,links:removedLinks}; | |||
} | |||
function addWorkspace(ws) { | |||
workspaces[ws.id] = ws; | |||
} | |||
function getWorkspace(id) { | |||
return workspaces[id]; | |||
} | |||
function removeWorkspace(id) { | |||
delete workspaces[id]; | |||
var removedNodes = []; | |||
var removedLinks = []; | |||
var n; | |||
for (n=0;n<nodes.length;n++) { | |||
var node = nodes[n]; | |||
if (node.z == id) { | |||
removedNodes.push(node); | |||
} | |||
} | |||
for (n=0;n<removedNodes.length;n++) { | |||
var rmlinks = removeNode(removedNodes[n].id); | |||
removedLinks = removedLinks.concat(rmlinks); | |||
} | |||
return {nodes:removedNodes,links:removedLinks}; | |||
} | |||
function getAllFlowNodes(node) { | |||
var visited = {}; | |||
visited[node.id] = true; | |||
var nns = [node]; | |||
var stack = [node]; | |||
while(stack.length !== 0) { | |||
var n = stack.shift(); | |||
var childLinks = links.filter(function(d) { return (d.source === n) || (d.target === n);}); | |||
for (var i=0;i<childLinks.length;i++) { | |||
var child = (childLinks[i].source === n)?childLinks[i].target:childLinks[i].source; | |||
if (!visited[child.id]) { | |||
visited[child.id] = true; | |||
nns.push(child); | |||
stack.push(child); | |||
} | |||
} | |||
} | |||
return nns; | |||
} | |||
function getAllFlowNodes(node) { | |||
var visited = {}; | |||
visited[node.id] = true; | |||
var nns = [node]; | |||
var stack = [node]; | |||
while(stack.length !== 0) { | |||
var n = stack.shift(); | |||
var childLinks = links.filter(function(d) { return (d.source === n) || (d.target === n);}); | |||
for (var i=0;i<childLinks.length;i++) { | |||
var child = (childLinks[i].source === n)?childLinks[i].target:childLinks[i].source; | |||
if (!visited[child.id]) { | |||
visited[child.id] = true; | |||
nns.push(child); | |||
stack.push(child); | |||
} | |||
} | |||
} | |||
return nns; | |||
} | |||
/** | |||
* Converts a node to an exportable JSON Object | |||
**/ | |||
function convertNode(n, exportCreds) { | |||
exportCreds = exportCreds || false; | |||
var node = {}; | |||
node.id = n.id; | |||
node.type = n.type; | |||
for (var d in n._def.defaults) { | |||
if (n._def.defaults.hasOwnProperty(d)) { | |||
node[d] = n[d]; | |||
} | |||
} | |||
if(exportCreds && n.credentials) { | |||
node.credentials = {}; | |||
for (var cred in n._def.credentials) { | |||
if (n._def.credentials.hasOwnProperty(cred)) { | |||
if (n.credentials[cred] != null) { | |||
node.credentials[cred] = n.credentials[cred]; | |||
} | |||
} | |||
} | |||
} | |||
if (n._def.category != "config") { | |||
node.x = n.x; | |||
node.y = n.y; | |||
node.z = n.z; | |||
node.wires = []; | |||
for(var i=0;i<n.outputs;i++) { | |||
node.wires.push([]); | |||
} | |||
var wires = links.filter(function(d){return d.source === n;}); | |||
for (var j=0;j<wires.length;j++) { | |||
var w = wires[j]; | |||
node.wires[w.sourcePort].push(w.target.id); | |||
} | |||
} | |||
return node; | |||
} | |||
/** | |||
* Converts a node to an exportable JSON Object | |||
**/ | |||
function convertNode(n, exportCreds) { | |||
exportCreds = exportCreds || false; | |||
var node = {}; | |||
node.id = n.id; | |||
node.type = n.type; | |||
for (var d in n._def.defaults) { | |||
if (n._def.defaults.hasOwnProperty(d)) { | |||
node[d] = n[d]; | |||
} | |||
} | |||
if(exportCreds && n.credentials) { | |||
node.credentials = {}; | |||
for (var cred in n._def.credentials) { | |||
if (n._def.credentials.hasOwnProperty(cred)) { | |||
if (n.credentials[cred] != null) { | |||
node.credentials[cred] = n.credentials[cred]; | |||
} | |||
} | |||
} | |||
} | |||
if (n._def.category != "config") { | |||
node.x = n.x; | |||
node.y = n.y; | |||
node.z = n.z; | |||
node.wires = []; | |||
for(var i=0;i<n.outputs;i++) { | |||
node.wires.push([]); | |||
} | |||
var wires = links.filter(function(d){return d.source === n;}); | |||
for (var j=0;j<wires.length;j++) { | |||
var w = wires[j]; | |||
node.wires[w.sourcePort].push(w.target.id); | |||
} | |||
} | |||
return node; | |||
} | |||
/** | |||
* Converts the current node selection to an exportable JSON Object | |||
**/ | |||
function createExportableNodeSet(set) { | |||
var nns = []; | |||
var exportedConfigNodes = {}; | |||
for (var n=0;n<set.length;n++) { | |||
var node = set[n].n; | |||
var convertedNode = RED.nodes.convertNode(node); | |||
for (var d in node._def.defaults) { | |||
if (node._def.defaults[d].type && node[d] in configNodes) { | |||
var confNode = configNodes[node[d]]; | |||
var exportable = getType(node._def.defaults[d].type).exportable; | |||
if ((exportable == null || exportable)) { | |||
if (!(node[d] in exportedConfigNodes)) { | |||
exportedConfigNodes[node[d]] = true; | |||
nns.unshift(RED.nodes.convertNode(confNode)); | |||
} | |||
} else { | |||
convertedNode[d] = ""; | |||
} | |||
} | |||
} | |||
/** | |||
* Converts the current node selection to an exportable JSON Object | |||
**/ | |||
function createExportableNodeSet(set) { | |||
var nns = []; | |||
var exportedConfigNodes = {}; | |||
for (var n=0;n<set.length;n++) { | |||
var node = set[n].n; | |||
var convertedNode = RED.nodes.convertNode(node); | |||
for (var d in node._def.defaults) { | |||
if (node._def.defaults[d].type && node[d] in configNodes) { | |||
var confNode = configNodes[node[d]]; | |||
var exportable = getType(node._def.defaults[d].type).exportable; | |||
if ((exportable == null || exportable)) { | |||
if (!(node[d] in exportedConfigNodes)) { | |||
exportedConfigNodes[node[d]] = true; | |||
nns.unshift(RED.nodes.convertNode(confNode)); | |||
} | |||
} else { | |||
convertedNode[d] = ""; | |||
} | |||
} | |||
} | |||
nns.push(convertedNode); | |||
} | |||
return nns; | |||
} | |||
nns.push(convertedNode); | |||
} | |||
return nns; | |||
} | |||
//TODO: rename this (createCompleteNodeSet) | |||
function createCompleteNodeSet() { | |||
var nns = []; | |||
var i; | |||
for (i in workspaces) { | |||
if (workspaces.hasOwnProperty(i)) { | |||
nns.push(workspaces[i]); | |||
} | |||
} | |||
for (i in configNodes) { | |||
if (configNodes.hasOwnProperty(i)) { | |||
nns.push(convertNode(configNodes[i], true)); | |||
} | |||
} | |||
for (i=0;i<nodes.length;i++) { | |||
var node = nodes[i]; | |||
nns.push(convertNode(node, true)); | |||
} | |||
return nns; | |||
} | |||
//TODO: rename this (createCompleteNodeSet) | |||
function createCompleteNodeSet() { | |||
var nns = []; | |||
var i; | |||
for (i in workspaces) { | |||
if (workspaces.hasOwnProperty(i)) { | |||
nns.push(workspaces[i]); | |||
} | |||
} | |||
for (i in configNodes) { | |||
if (configNodes.hasOwnProperty(i)) { | |||
nns.push(convertNode(configNodes[i], true)); | |||
} | |||
} | |||
for (i=0;i<nodes.length;i++) { | |||
var node = nodes[i]; | |||
nns.push(convertNode(node, true)); | |||
} | |||
return nns; | |||
} | |||
function importNodes(newNodesObj,createNewIds) { | |||
try { | |||
var i; | |||
var n; | |||
var newNodes; | |||
if (typeof newNodesObj === "string") { | |||
if (newNodesObj === "") { | |||
return; | |||
} | |||
newNodes = JSON.parse(newNodesObj); | |||
} else { | |||
newNodes = newNodesObj; | |||
} | |||
function importNodes(newNodesObj,createNewIds) { | |||
try { | |||
var i; | |||
var n; | |||
var newNodes; | |||
if (typeof newNodesObj === "string") { | |||
if (newNodesObj === "") { | |||
return; | |||
} | |||
newNodes = JSON.parse(newNodesObj); | |||
} else { | |||
newNodes = newNodesObj; | |||
} | |||
if (!$.isArray(newNodes)) { | |||
newNodes = [newNodes]; | |||
} | |||
var unknownTypes = []; | |||
for (i=0;i<newNodes.length;i++) { | |||
n = newNodes[i]; | |||
// TODO: remove workspace in next release+1 | |||
if (n.type != "workspace" && n.type != "tab" && !getType(n.type)) { | |||
// TODO: get this UI thing out of here! (see below as well) | |||
n.name = n.type; | |||
n.type = "unknown"; | |||
if (unknownTypes.indexOf(n.name)==-1) { | |||
unknownTypes.push(n.name); | |||
} | |||
if (n.x == null && n.y == null) { | |||
// config node - remove it | |||
newNodes.splice(i,1); | |||
i--; | |||
} | |||
} | |||
} | |||
if (unknownTypes.length > 0) { | |||
var typeList = "<ul><li>"+unknownTypes.join("</li><li>")+"</li></ul>"; | |||
var type = "type"+(unknownTypes.length > 1?"s":""); | |||
RED.notify("<strong>Imported unrecognised "+type+":</strong>"+typeList,"error",false,10000); | |||
//"DO NOT DEPLOY while in this state.<br/>Either, add missing types to Node-RED, restart and then reload page,<br/>or delete unknown "+n.name+", rewire as required, and then deploy.","error"); | |||
} | |||
if (!$.isArray(newNodes)) { | |||
newNodes = [newNodes]; | |||
} | |||
var unknownTypes = []; | |||
for (i=0;i<newNodes.length;i++) { | |||
n = newNodes[i]; | |||
// TODO: remove workspace in next release+1 | |||
if (n.type != "workspace" && n.type != "tab" && !getType(n.type)) { | |||
// TODO: get this UI thing out of here! (see below as well) | |||
n.name = n.type; | |||
n.type = "unknown"; | |||
if (unknownTypes.indexOf(n.name)==-1) { | |||
unknownTypes.push(n.name); | |||
} | |||
if (n.x == null && n.y == null) { | |||
// config node - remove it | |||
newNodes.splice(i,1); | |||
i--; | |||
} | |||
} | |||
} | |||
if (unknownTypes.length > 0) { | |||
var typeList = "<ul><li>"+unknownTypes.join("</li><li>")+"</li></ul>"; | |||
var type = "type"+(unknownTypes.length > 1?"s":""); | |||
RED.notify("<strong>Imported unrecognised "+type+":</strong>"+typeList,"error",false,10000); | |||
//"DO NOT DEPLOY while in this state.<br/>Either, add missing types to Node-RED, restart and then reload page,<br/>or delete unknown "+n.name+", rewire as required, and then deploy.","error"); | |||
} | |||
for (i=0;i<newNodes.length;i++) { | |||
n = newNodes[i]; | |||
// TODO: remove workspace in next release+1 | |||
if (n.type === "workspace" || n.type === "tab") { | |||
if (n.type === "workspace") { | |||
n.type = "tab"; | |||
} | |||
if (defaultWorkspace == null) { | |||
defaultWorkspace = n; | |||
} | |||
addWorkspace(n); | |||
RED.view.addWorkspace(n); | |||
} | |||
} | |||
if (defaultWorkspace == null) { | |||
defaultWorkspace = { type:"tab", id:getID(), label:"Sheet 1" }; | |||
addWorkspace(defaultWorkspace); | |||
RED.view.addWorkspace(defaultWorkspace); | |||
} | |||
for (i=0;i<newNodes.length;i++) { | |||
n = newNodes[i]; | |||
// TODO: remove workspace in next release+1 | |||
if (n.type === "workspace" || n.type === "tab") { | |||
if (n.type === "workspace") { | |||
n.type = "tab"; | |||
} | |||
if (defaultWorkspace == null) { | |||
defaultWorkspace = n; | |||
} | |||
addWorkspace(n); | |||
RED.view.addWorkspace(n); | |||
} | |||
} | |||
if (defaultWorkspace == null) { | |||
defaultWorkspace = { type:"tab", id:getID(), label:"Sheet 1" }; | |||
addWorkspace(defaultWorkspace); | |||
RED.view.addWorkspace(defaultWorkspace); | |||
} | |||
var node_map = {}; | |||
var new_nodes = []; | |||
var new_links = []; | |||
var node_map = {}; | |||
var new_nodes = []; | |||
var new_links = []; | |||
for (i=0;i<newNodes.length;i++) { | |||
n = newNodes[i]; | |||
// TODO: remove workspace in next release+1 | |||
if (n.type !== "workspace" && n.type !== "tab") { | |||
var def = getType(n.type); | |||
if (def && def.category == "config") { | |||
if (!RED.nodes.node(n.id)) { | |||
var configNode = {id:n.id,type:n.type,users:[]}; | |||
for (var d in def.defaults) { | |||
if (def.defaults.hasOwnProperty(d)) { | |||
configNode[d] = n[d]; | |||
} | |||
} | |||
configNode.label = def.label; | |||
configNode._def = def; | |||
RED.nodes.add(configNode); | |||
} | |||
} else { | |||
var node = {x:n.x,y:n.y,z:n.z,type:0,wires:n.wires,changed:false}; | |||
if (createNewIds) { | |||
node.z = RED.view.getWorkspace(); | |||
node.id = getID(); | |||
} else { | |||
node.id = n.id; | |||
if (node.z == null || !workspaces[node.z]) { | |||
node.z = RED.view.getWorkspace(); | |||
} | |||
} | |||
node.type = n.type; | |||
node._def = def; | |||
if (!node._def) { | |||
node._def = { | |||
color:"#fee", | |||
defaults: {}, | |||
label: "unknown: "+n.type, | |||
labelStyle: "node_label_italic", | |||
outputs: n.outputs||n.wires.length | |||
} | |||
} | |||
node.outputs = n.outputs||node._def.outputs; | |||
for (i=0;i<newNodes.length;i++) { | |||
n = newNodes[i]; | |||
// TODO: remove workspace in next release+1 | |||
if (n.type !== "workspace" && n.type !== "tab") { | |||
var def = getType(n.type); | |||
if (def && def.category == "config") { | |||
if (!RED.nodes.node(n.id)) { | |||
var configNode = {id:n.id,type:n.type,users:[]}; | |||
for (var d in def.defaults) { | |||
if (def.defaults.hasOwnProperty(d)) { | |||
configNode[d] = n[d]; | |||
} | |||
} | |||
configNode.label = def.label; | |||
configNode._def = def; | |||
RED.nodes.add(configNode); | |||
} | |||
} else { | |||
var node = {x:n.x,y:n.y,z:n.z,type:0,wires:n.wires,changed:false}; | |||
if (createNewIds) { | |||
node.z = RED.view.getWorkspace(); | |||
node.id = getID(); | |||
} else { | |||
node.id = n.id; | |||
if (node.z == null || !workspaces[node.z]) { | |||
node.z = RED.view.getWorkspace(); | |||
} | |||
} | |||
node.type = n.type; | |||
node._def = def; | |||
if (!node._def) { | |||
node._def = { | |||
color:"#fee", | |||
defaults: {}, | |||
label: "unknown: "+n.type, | |||
labelStyle: "node_label_italic", | |||
outputs: n.outputs||n.wires.length | |||
} | |||
} | |||
node.outputs = n.outputs||node._def.outputs; | |||
for (var d2 in node._def.defaults) { | |||
if (node._def.defaults.hasOwnProperty(d2)) { | |||
node[d2] = n[d2]; | |||
} | |||
} | |||
for (var d2 in node._def.defaults) { | |||
if (node._def.defaults.hasOwnProperty(d2)) { | |||
node[d2] = n[d2]; | |||
} | |||
} | |||
addNode(node); | |||
RED.editor.validateNode(node); | |||
node_map[n.id] = node; | |||
new_nodes.push(node); | |||
} | |||
} | |||
} | |||
for (i=0;i<new_nodes.length;i++) { | |||
n = new_nodes[i]; | |||
for (var w1=0;w1<n.wires.length;w1++) { | |||
var wires = (n.wires[w1] instanceof Array)?n.wires[w1]:[n.wires[w1]]; | |||
for (var w2=0;w2<wires.length;w2++) { | |||
if (wires[w2] in node_map) { | |||
var link = {source:n,sourcePort:w1,target:node_map[wires[w2]]}; | |||
addLink(link); | |||
new_links.push(link); | |||
} | |||
} | |||
} | |||
delete n.wires; | |||
} | |||
return [new_nodes,new_links]; | |||
} catch(error) { | |||
//TODO: get this UI thing out of here! (see above as well) | |||
RED.notify("<strong>Error</strong>: "+error,"error"); | |||
return null; | |||
} | |||
addNode(node); | |||
RED.editor.validateNode(node); | |||
node_map[n.id] = node; | |||
new_nodes.push(node); | |||
} | |||
} | |||
} | |||
for (i=0;i<new_nodes.length;i++) { | |||
n = new_nodes[i]; | |||
for (var w1=0;w1<n.wires.length;w1++) { | |||
var wires = (n.wires[w1] instanceof Array)?n.wires[w1]:[n.wires[w1]]; | |||
for (var w2=0;w2<wires.length;w2++) { | |||
if (wires[w2] in node_map) { | |||
var link = {source:n,sourcePort:w1,target:node_map[wires[w2]]}; | |||
addLink(link); | |||
new_links.push(link); | |||
} | |||
} | |||
} | |||
delete n.wires; | |||
} | |||
return [new_nodes,new_links]; | |||
} catch(error) { | |||
//TODO: get this UI thing out of here! (see above as well) | |||
RED.notify("<strong>Error</strong>: "+error,"error"); | |||
return null; | |||
} | |||
} | |||
} | |||
return { | |||
registerType: registerType, | |||
getType: getType, | |||
convertNode: convertNode, | |||
add: addNode, | |||
addLink: addLink, | |||
remove: removeNode, | |||
removeLink: removeLink, | |||
addWorkspace: addWorkspace, | |||
removeWorkspace: removeWorkspace, | |||
workspace: getWorkspace, | |||
eachNode: function(cb) { | |||
for (var n=0;n<nodes.length;n++) { | |||
cb(nodes[n]); | |||
} | |||
}, | |||
eachLink: function(cb) { | |||
for (var l=0;l<links.length;l++) { | |||
cb(links[l]); | |||
} | |||
}, | |||
eachConfig: function(cb) { | |||
for (var id in configNodes) { | |||
if (configNodes.hasOwnProperty(id)) { | |||
cb(configNodes[id]); | |||
} | |||
} | |||
}, | |||
node: getNode, | |||
import: importNodes, | |||
refreshValidation: refreshValidation, | |||
getAllFlowNodes: getAllFlowNodes, | |||
createExportableNodeSet: createExportableNodeSet, | |||
createCompleteNodeSet: createCompleteNodeSet, | |||
id: getID, | |||
cppName: createUniqueCppName, | |||
nodes: nodes, // TODO: exposed for d3 vis | |||
links: links // TODO: exposed for d3 vis | |||
}; | |||
return { | |||
registerType: registerType, | |||
getType: getType, | |||
convertNode: convertNode, | |||
add: addNode, | |||
addLink: addLink, | |||
remove: removeNode, | |||
removeLink: removeLink, | |||
addWorkspace: addWorkspace, | |||
removeWorkspace: removeWorkspace, | |||
workspace: getWorkspace, | |||
eachNode: function(cb) { | |||
for (var n=0;n<nodes.length;n++) { | |||
cb(nodes[n]); | |||
} | |||
}, | |||
eachLink: function(cb) { | |||
for (var l=0;l<links.length;l++) { | |||
cb(links[l]); | |||
} | |||
}, | |||
eachConfig: function(cb) { | |||
for (var id in configNodes) { | |||
if (configNodes.hasOwnProperty(id)) { | |||
cb(configNodes[id]); | |||
} | |||
} | |||
}, | |||
node: getNode, | |||
import: importNodes, | |||
refreshValidation: refreshValidation, | |||
getAllFlowNodes: getAllFlowNodes, | |||
createExportableNodeSet: createExportableNodeSet, | |||
createCompleteNodeSet: createCompleteNodeSet, | |||
id: getID, | |||
cppName: createUniqueCppName, | |||
nodes: nodes, // TODO: exposed for d3 vis | |||
links: links // TODO: exposed for d3 vis | |||
}; | |||
})(); |
@@ -1,4 +1,5 @@ | |||
/** | |||
/** Modified from original Node-Red source, for audio system visualization | |||
* vim: set ts=4: | |||
* Copyright 2013 IBM Corp. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
@@ -15,54 +16,54 @@ | |||
**/ | |||
RED.keyboard = (function() { | |||
var active = true; | |||
var handlers = {}; | |||
var active = true; | |||
var handlers = {}; | |||
d3.select(window).on("keydown",function() { | |||
if (!active) { return; } | |||
var handler = handlers[d3.event.keyCode]; | |||
if (handler && handler.ondown) { | |||
if (!handler.modifiers || | |||
((!handler.modifiers.shift || d3.event.shiftKey) && | |||
(!handler.modifiers.ctrl || d3.event.ctrlKey ) && | |||
(!handler.modifiers.alt || d3.event.altKey ) )) { | |||
handler.ondown(); | |||
} | |||
} | |||
}); | |||
d3.select(window).on("keyup",function() { | |||
if (!active) { return; } | |||
var handler = handlers[d3.event.keyCode]; | |||
if (handler && handler.onup) { | |||
if (!handler.modifiers || | |||
((!handler.modifiers.shift || d3.event.shiftKey) && | |||
(!handler.modifiers.ctrl || d3.event.ctrlKey ) && | |||
(!handler.modifiers.alt || d3.event.altKey ) )) { | |||
handler.onup(); | |||
} | |||
} | |||
}); | |||
function addHandler(key,modifiers,ondown,onup) { | |||
var mod = modifiers; | |||
var cbdown = ondown; | |||
var cbup = onup; | |||
d3.select(window).on("keydown",function() { | |||
if (!active) { return; } | |||
var handler = handlers[d3.event.keyCode]; | |||
if (handler && handler.ondown) { | |||
if (!handler.modifiers || | |||
((!handler.modifiers.shift || d3.event.shiftKey) && | |||
(!handler.modifiers.ctrl || d3.event.ctrlKey ) && | |||
(!handler.modifiers.alt || d3.event.altKey ) )) { | |||
handler.ondown(); | |||
} | |||
} | |||
}); | |||
d3.select(window).on("keyup",function() { | |||
if (!active) { return; } | |||
var handler = handlers[d3.event.keyCode]; | |||
if (handler && handler.onup) { | |||
if (!handler.modifiers || | |||
((!handler.modifiers.shift || d3.event.shiftKey) && | |||
(!handler.modifiers.ctrl || d3.event.ctrlKey ) && | |||
(!handler.modifiers.alt || d3.event.altKey ) )) { | |||
handler.onup(); | |||
} | |||
} | |||
}); | |||
function addHandler(key,modifiers,ondown,onup) { | |||
var mod = modifiers; | |||
var cbdown = ondown; | |||
var cbup = onup; | |||
if (typeof modifiers == "function") { | |||
mod = {}; | |||
cbdown = modifiers; | |||
cbup = ondown; | |||
} | |||
handlers[key] = {modifiers:mod, ondown:cbdown, onup:cbup}; | |||
} | |||
function removeHandler(key) { | |||
delete handlers[key]; | |||
} | |||
if (typeof modifiers == "function") { | |||
mod = {}; | |||
cbdown = modifiers; | |||
cbup = ondown; | |||
} | |||
handlers[key] = {modifiers:mod, ondown:cbdown, onup:cbup}; | |||
} | |||
function removeHandler(key) { | |||
delete handlers[key]; | |||
} | |||
return { | |||
add: addHandler, | |||
remove: removeHandler, | |||
disable: function(){ active = false;}, | |||
enable: function(){ active = true; } | |||
} | |||
return { | |||
add: addHandler, | |||
remove: removeHandler, | |||
disable: function(){ active = false;}, | |||
enable: function(){ active = true; } | |||
} | |||
})(); |
@@ -1,4 +1,5 @@ | |||
/** | |||
/** Modified from original Node-Red source, for audio system visualization | |||
* vim: set ts=4: | |||
* Copyright 2013 IBM Corp. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
@@ -14,354 +15,354 @@ | |||
* limitations under the License. | |||
**/ | |||
RED.library = (function() { | |||
function loadFlowLibrary() { | |||
$.getJSON("library/flows",function(data) { | |||
//console.log(data); | |||
function loadFlowLibrary() { | |||
$.getJSON("library/flows",function(data) { | |||
//console.log(data); | |||
var buildMenu = function(data,root) { | |||
var i; | |||
var li; | |||
var a; | |||
var ul = document.createElement("ul"); | |||
ul.className = "dropdown-menu"; | |||
if (data.d) { | |||
for (i in data.d) { | |||
if (data.d.hasOwnProperty(i)) { | |||
li = document.createElement("li"); | |||
li.className = "dropdown-submenu pull-left"; | |||
a = document.createElement("a"); | |||
a.href="#"; | |||
a.innerHTML = i; | |||
li.appendChild(a); | |||
li.appendChild(buildMenu(data.d[i],root+(root!==""?"/":"")+i)); | |||
ul.appendChild(li); | |||
} | |||
} | |||
} | |||
if (data.f) { | |||
for (i in data.f) { | |||
if (data.f.hasOwnProperty(i)) { | |||
li = document.createElement("li"); | |||
a = document.createElement("a"); | |||
a.href="#"; | |||
a.innerHTML = data.f[i]; | |||
a.flowName = root+(root!==""?"/":"")+data.f[i]; | |||
a.onclick = function() { | |||
$.get('library/flows/'+this.flowName, function(data) { | |||
RED.view.importNodes(data); | |||
}); | |||
}; | |||
li.appendChild(a); | |||
ul.appendChild(li); | |||
} | |||
} | |||
} | |||
return ul; | |||
}; | |||
var menu = buildMenu(data,""); | |||
$("#flow-menu-parent>ul").replaceWith(menu); | |||
}); | |||
} | |||
loadFlowLibrary(); | |||
var buildMenu = function(data,root) { | |||
var i; | |||
var li; | |||
var a; | |||
var ul = document.createElement("ul"); | |||
ul.className = "dropdown-menu"; | |||
if (data.d) { | |||
for (i in data.d) { | |||
if (data.d.hasOwnProperty(i)) { | |||
li = document.createElement("li"); | |||
li.className = "dropdown-submenu pull-left"; | |||
a = document.createElement("a"); | |||
a.href="#"; | |||
a.innerHTML = i; | |||
li.appendChild(a); | |||
li.appendChild(buildMenu(data.d[i],root+(root!==""?"/":"")+i)); | |||
ul.appendChild(li); | |||
} | |||
} | |||
} | |||
if (data.f) { | |||
for (i in data.f) { | |||
if (data.f.hasOwnProperty(i)) { | |||
li = document.createElement("li"); | |||
a = document.createElement("a"); | |||
a.href="#"; | |||
a.innerHTML = data.f[i]; | |||
a.flowName = root+(root!==""?"/":"")+data.f[i]; | |||
a.onclick = function() { | |||
$.get('library/flows/'+this.flowName, function(data) { | |||
RED.view.importNodes(data); | |||
}); | |||
}; | |||
li.appendChild(a); | |||
ul.appendChild(li); | |||
} | |||
} | |||
} | |||
return ul; | |||
}; | |||
var menu = buildMenu(data,""); | |||
$("#flow-menu-parent>ul").replaceWith(menu); | |||
}); | |||
} | |||
loadFlowLibrary(); | |||
function createUI(options) { | |||
var libraryData = {}; | |||
var selectedLibraryItem = null; | |||
var libraryEditor = null; | |||
function buildFileListItem(item) { | |||
var li = document.createElement("li"); | |||
li.onmouseover = function(e) { $(this).addClass("list-hover"); }; | |||
li.onmouseout = function(e) { $(this).removeClass("list-hover"); }; | |||
return li; | |||
} | |||
function buildFileList(root,data) { | |||
var ul = document.createElement("ul"); | |||
var li; | |||
for (var i=0;i<data.length;i++) { | |||
var v = data[i]; | |||
if (typeof v === "string") { | |||
// directory | |||
li = buildFileListItem(v); | |||
li.onclick = (function () { | |||
var dirName = v; | |||
return function(e) { | |||
var bcli = $('<li class="active"><span class="divider">/</span> <a href="#">'+dirName+'</a></li>'); | |||
$("a",bcli).click(function(e) { | |||
$(this).parent().nextAll().remove(); | |||
$.getJSON("library/"+options.url+root+dirName,function(data) { | |||
$("#node-select-library").children().first().replaceWith(buildFileList(root+dirName+"/",data)); | |||
}); | |||
e.stopPropagation(); | |||
}); | |||
var bc = $("#node-dialog-library-breadcrumbs"); | |||
$(".active",bc).removeClass("active"); | |||
bc.append(bcli); | |||
$.getJSON("library/"+options.url+root+dirName,function(data) { | |||
$("#node-select-library").children().first().replaceWith(buildFileList(root+dirName+"/",data)); | |||
}); | |||
} | |||
})(); | |||
li.innerHTML = '<i class="icon-folder-close"></i> '+v+"</i>"; | |||
ul.appendChild(li); | |||
} else { | |||
// file | |||
li = buildFileListItem(v); | |||
li.innerHTML = v.name; | |||
li.onclick = (function() { | |||
var item = v; | |||
return function(e) { | |||
$(".list-selected",ul).removeClass("list-selected"); | |||
$(this).addClass("list-selected"); | |||
$.get("library/"+options.url+root+item.fn, function(data) { | |||
console.log(data); | |||
selectedLibraryItem = item; | |||
libraryEditor.setText(data); | |||
}); | |||
} | |||
})(); | |||
ul.appendChild(li); | |||
} | |||
} | |||
return ul; | |||
} | |||
$('#node-input-name').addClass('input-append-left').css("width","65%").after( | |||
'<div class="btn-group" style="margin-left: -5px;">'+ | |||
'<button id="node-input-'+options.type+'-lookup" class="btn input-append-right" data-toggle="dropdown"><i class="icon-book"></i> <span class="caret"></span></button>'+ | |||
'<ul class="dropdown-menu pull-right" role="menu">'+ | |||
'<li><a id="node-input-'+options.type+'-menu-open-library" tabindex="-1" href="#">Open Library...</a></li>'+ | |||
'<li><a id="node-input-'+options.type+'-menu-save-library" tabindex="-1" href="#">Save to Library...</a></li>'+ | |||
'</ul></div>' | |||
); | |||
$('#node-input-'+options.type+'-menu-open-library').click(function(e) { | |||
$("#node-select-library").children().remove(); | |||
var bc = $("#node-dialog-library-breadcrumbs"); | |||
bc.children().first().nextAll().remove(); | |||
libraryEditor.setText(''); | |||
$.getJSON("library/"+options.url,function(data) { | |||
$("#node-select-library").append(buildFileList("/",data)); | |||
$("#node-dialog-library-breadcrumbs a").click(function(e) { | |||
$(this).parent().nextAll().remove(); | |||
$("#node-select-library").children().first().replaceWith(buildFileList("/",data)); | |||
e.stopPropagation(); | |||
}); | |||
$( "#node-dialog-library-lookup" ).dialog( "open" ); | |||
}); | |||
e.preventDefault(); | |||
}); | |||
$('#node-input-'+options.type+'-menu-save-library').click(function(e) { | |||
//var found = false; | |||
var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,""); | |||
function createUI(options) { | |||
var libraryData = {}; | |||
var selectedLibraryItem = null; | |||
var libraryEditor = null; | |||
function buildFileListItem(item) { | |||
var li = document.createElement("li"); | |||
li.onmouseover = function(e) { $(this).addClass("list-hover"); }; | |||
li.onmouseout = function(e) { $(this).removeClass("list-hover"); }; | |||
return li; | |||
} | |||
function buildFileList(root,data) { | |||
var ul = document.createElement("ul"); | |||
var li; | |||
for (var i=0;i<data.length;i++) { | |||
var v = data[i]; | |||
if (typeof v === "string") { | |||
// directory | |||
li = buildFileListItem(v); | |||
li.onclick = (function () { | |||
var dirName = v; | |||
return function(e) { | |||
var bcli = $('<li class="active"><span class="divider">/</span> <a href="#">'+dirName+'</a></li>'); | |||
$("a",bcli).click(function(e) { | |||
$(this).parent().nextAll().remove(); | |||
$.getJSON("library/"+options.url+root+dirName,function(data) { | |||
$("#node-select-library").children().first().replaceWith(buildFileList(root+dirName+"/",data)); | |||
}); | |||
e.stopPropagation(); | |||
}); | |||
var bc = $("#node-dialog-library-breadcrumbs"); | |||
$(".active",bc).removeClass("active"); | |||
bc.append(bcli); | |||
$.getJSON("library/"+options.url+root+dirName,function(data) { | |||
$("#node-select-library").children().first().replaceWith(buildFileList(root+dirName+"/",data)); | |||
}); | |||
} | |||
})(); | |||
li.innerHTML = '<i class="icon-folder-close"></i> '+v+"</i>"; | |||
ul.appendChild(li); | |||
} else { | |||
// file | |||
li = buildFileListItem(v); | |||
li.innerHTML = v.name; | |||
li.onclick = (function() { | |||
var item = v; | |||
return function(e) { | |||
$(".list-selected",ul).removeClass("list-selected"); | |||
$(this).addClass("list-selected"); | |||
$.get("library/"+options.url+root+item.fn, function(data) { | |||
console.log(data); | |||
selectedLibraryItem = item; | |||
libraryEditor.setText(data); | |||
}); | |||
} | |||
})(); | |||
ul.appendChild(li); | |||
} | |||
} | |||
return ul; | |||
} | |||
$('#node-input-name').addClass('input-append-left').css("width","65%").after( | |||
'<div class="btn-group" style="margin-left: -5px;">'+ | |||
'<button id="node-input-'+options.type+'-lookup" class="btn input-append-right" data-toggle="dropdown"><i class="icon-book"></i> <span class="caret"></span></button>'+ | |||
'<ul class="dropdown-menu pull-right" role="menu">'+ | |||
'<li><a id="node-input-'+options.type+'-menu-open-library" tabindex="-1" href="#">Open Library...</a></li>'+ | |||
'<li><a id="node-input-'+options.type+'-menu-save-library" tabindex="-1" href="#">Save to Library...</a></li>'+ | |||
'</ul></div>' | |||
); | |||
$('#node-input-'+options.type+'-menu-open-library').click(function(e) { | |||
$("#node-select-library").children().remove(); | |||
var bc = $("#node-dialog-library-breadcrumbs"); | |||
bc.children().first().nextAll().remove(); | |||
libraryEditor.setText(''); | |||
$.getJSON("library/"+options.url,function(data) { | |||
$("#node-select-library").append(buildFileList("/",data)); | |||
$("#node-dialog-library-breadcrumbs a").click(function(e) { | |||
$(this).parent().nextAll().remove(); | |||
$("#node-select-library").children().first().replaceWith(buildFileList("/",data)); | |||
e.stopPropagation(); | |||
}); | |||
$( "#node-dialog-library-lookup" ).dialog( "open" ); | |||
}); | |||
e.preventDefault(); | |||
}); | |||
$('#node-input-'+options.type+'-menu-save-library').click(function(e) { | |||
//var found = false; | |||
var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,""); | |||
//var buildPathList = function(data,root) { | |||
// var paths = []; | |||
// if (data.d) { | |||
// for (var i in data.d) { | |||
// var dn = root+(root==""?"":"/")+i; | |||
// var d = { | |||
// label:dn, | |||
// files:[] | |||
// }; | |||
// for (var f in data.d[i].f) { | |||
// d.files.push(data.d[i].f[f].fn.split("/").slice(-1)[0]); | |||
// } | |||
// paths.push(d); | |||
// paths = paths.concat(buildPathList(data.d[i],root+(root==""?"":"/")+i)); | |||
// } | |||
// } | |||
// return paths; | |||
//}; | |||
$("#node-dialog-library-save-folder").attr("value",""); | |||
//var buildPathList = function(data,root) { | |||
// var paths = []; | |||
// if (data.d) { | |||
// for (var i in data.d) { | |||
// var dn = root+(root==""?"":"/")+i; | |||
// var d = { | |||
// label:dn, | |||
// files:[] | |||
// }; | |||
// for (var f in data.d[i].f) { | |||
// d.files.push(data.d[i].f[f].fn.split("/").slice(-1)[0]); | |||
// } | |||
// paths.push(d); | |||
// paths = paths.concat(buildPathList(data.d[i],root+(root==""?"":"/")+i)); | |||
// } | |||
// } | |||
// return paths; | |||
//}; | |||
$("#node-dialog-library-save-folder").attr("value",""); | |||
var filename = name.replace(/[^\w-]/g,"-"); | |||
if (filename === "") { | |||
filename = "unnamed-"+options.type; | |||
} | |||
$("#node-dialog-library-save-filename").attr("value",filename+".js"); | |||
var filename = name.replace(/[^\w-]/g,"-"); | |||
if (filename === "") { | |||
filename = "unnamed-"+options.type; | |||
} | |||
$("#node-dialog-library-save-filename").attr("value",filename+".js"); | |||
//var paths = buildPathList(libraryData,""); | |||
//$("#node-dialog-library-save-folder").autocomplete({ | |||
// minLength: 0, | |||
// source: paths, | |||
// select: function( event, ui ) { | |||
// $("#node-dialog-library-save-filename").autocomplete({ | |||
// minLength: 0, | |||
// source: ui.item.files | |||
// }); | |||
// } | |||
//}); | |||
//var paths = buildPathList(libraryData,""); | |||
//$("#node-dialog-library-save-folder").autocomplete({ | |||
// minLength: 0, | |||
// source: paths, | |||
// select: function( event, ui ) { | |||
// $("#node-dialog-library-save-filename").autocomplete({ | |||
// minLength: 0, | |||
// source: ui.item.files | |||
// }); | |||
// } | |||
//}); | |||
$( "#node-dialog-library-save" ).dialog( "open" ); | |||
e.preventDefault(); | |||
}); | |||
require(["orion/editor/edit"], function(edit) { | |||
libraryEditor = edit({ | |||
parent:document.getElementById('node-select-library-text'), | |||
lang:"js", | |||
readonly: true | |||
}); | |||
}); | |||
$( "#node-dialog-library-lookup" ).dialog({ | |||
title: options.type+" library", | |||
modal: true, | |||
autoOpen: false, | |||
width: 800, | |||
height: 450, | |||
buttons: [ | |||
{ | |||
text: "Ok", | |||
click: function() { | |||
if (selectedLibraryItem) { | |||
for (var i=0;i<options.fields.length;i++) { | |||
var field = options.fields[i]; | |||
$("#node-input-"+field).val(selectedLibraryItem[field]); | |||
} | |||
options.editor.setText(libraryEditor.getText()); | |||
} | |||
$( this ).dialog( "close" ); | |||
} | |||
}, | |||
{ | |||
text: "Cancel", | |||
click: function() { | |||
$( this ).dialog( "close" ); | |||
} | |||
} | |||
], | |||
open: function(e) { | |||
var form = $("form",this); | |||
form.height(form.parent().height()-30); | |||
$("#node-select-library-text").height("100%"); | |||
$(".form-row:last-child",form).children().height(form.height()-60); | |||
}, | |||
resize: function(e) { | |||
var form = $("form",this); | |||
form.height(form.parent().height()-30); | |||
$(".form-row:last-child",form).children().height(form.height()-60); | |||
} | |||
}); | |||
function saveToLibrary(overwrite) { | |||
var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,""); | |||
if (name === "") { | |||
name = "Unnamed "+options.type; | |||
} | |||
var filename = $("#node-dialog-library-save-filename").val().replace(/(^\s*)|(\s*$)/g,""); | |||
var pathname = $("#node-dialog-library-save-folder").val().replace(/(^\s*)|(\s*$)/g,""); | |||
if (filename === "" || !/.+\.js$/.test(filename)) { | |||
RED.notify("Invalid filename","warning"); | |||
return; | |||
} | |||
var fullpath = pathname+(pathname===""?"":"/")+filename; | |||
if (!overwrite) { | |||
//var pathnameParts = pathname.split("/"); | |||
//var exists = false; | |||
//var ds = libraryData; | |||
//for (var pnp in pathnameParts) { | |||
// if (ds.d && pathnameParts[pnp] in ds.d) { | |||
// ds = ds.d[pathnameParts[pnp]]; | |||
// } else { | |||
// ds = null; | |||
// break; | |||
// } | |||
//} | |||
//if (ds && ds.f) { | |||
// for (var f in ds.f) { | |||
// if (ds.f[f].fn == fullpath) { | |||
// exists = true; | |||
// break; | |||
// } | |||
// } | |||
//} | |||
//if (exists) { | |||
// $("#node-dialog-library-save-type").html(options.type); | |||
// $("#node-dialog-library-save-name").html(fullpath); | |||
// $("#node-dialog-library-save-confirm").dialog( "open" ); | |||
// return; | |||
//} | |||
} | |||
var queryArgs = []; | |||
for (var i=0;i<options.fields.length;i++) { | |||
var field = options.fields[i]; | |||
if (field == "name") { | |||
queryArgs.push("name="+encodeURIComponent(name)); | |||
} else { | |||
queryArgs.push(encodeURIComponent(field)+"="+encodeURIComponent($("#node-input-"+field).val())); | |||
} | |||
} | |||
var queryString = queryArgs.join("&"); | |||
var text = options.editor.getText(); | |||
$.post("library/"+options.url+'/'+fullpath+"?"+queryString,text,function() { | |||
RED.notify("Saved "+options.type,"success"); | |||
}); | |||
} | |||
$( "#node-dialog-library-save-confirm" ).dialog({ | |||
title: "Save to library", | |||
modal: true, | |||
autoOpen: false, | |||
width: 530, | |||
height: 230, | |||
buttons: [ | |||
{ | |||
text: "Ok", | |||
click: function() { | |||
saveToLibrary(true); | |||
$( this ).dialog( "close" ); | |||
} | |||
}, | |||
{ | |||
text: "Cancel", | |||
click: function() { | |||
$( this ).dialog( "close" ); | |||
} | |||
} | |||
] | |||
}); | |||
$( "#node-dialog-library-save" ).dialog({ | |||
title: "Save to library", | |||
modal: true, | |||
autoOpen: false, | |||
width: 530, | |||
height: 230, | |||
buttons: [ | |||
{ | |||
text: "Ok", | |||
click: function() { | |||
saveToLibrary(false); | |||
$( this ).dialog( "close" ); | |||
} | |||
}, | |||
{ | |||
text: "Cancel", | |||
click: function() { | |||
$( this ).dialog( "close" ); | |||
} | |||
} | |||
] | |||
}); | |||
$( "#node-dialog-library-save" ).dialog( "open" ); | |||
e.preventDefault(); | |||
}); | |||
require(["orion/editor/edit"], function(edit) { | |||
libraryEditor = edit({ | |||
parent:document.getElementById('node-select-library-text'), | |||
lang:"js", | |||
readonly: true | |||
}); | |||
}); | |||
$( "#node-dialog-library-lookup" ).dialog({ | |||
title: options.type+" library", | |||
modal: true, | |||
autoOpen: false, | |||
width: 800, | |||
height: 450, | |||
buttons: [ | |||
{ | |||
text: "Ok", | |||
click: function() { | |||
if (selectedLibraryItem) { | |||
for (var i=0;i<options.fields.length;i++) { | |||
var field = options.fields[i]; | |||
$("#node-input-"+field).val(selectedLibraryItem[field]); | |||
} | |||
options.editor.setText(libraryEditor.getText()); | |||
} | |||
$( this ).dialog( "close" ); | |||
} | |||
}, | |||
{ | |||
text: "Cancel", | |||
click: function() { | |||
$( this ).dialog( "close" ); | |||
} | |||
} | |||
], | |||
open: function(e) { | |||
var form = $("form",this); | |||
form.height(form.parent().height()-30); | |||
$("#node-select-library-text").height("100%"); | |||
$(".form-row:last-child",form).children().height(form.height()-60); | |||
}, | |||
resize: function(e) { | |||
var form = $("form",this); | |||
form.height(form.parent().height()-30); | |||
$(".form-row:last-child",form).children().height(form.height()-60); | |||
} | |||
}); | |||
function saveToLibrary(overwrite) { | |||
var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,""); | |||
if (name === "") { | |||
name = "Unnamed "+options.type; | |||
} | |||
var filename = $("#node-dialog-library-save-filename").val().replace(/(^\s*)|(\s*$)/g,""); | |||
var pathname = $("#node-dialog-library-save-folder").val().replace(/(^\s*)|(\s*$)/g,""); | |||
if (filename === "" || !/.+\.js$/.test(filename)) { | |||
RED.notify("Invalid filename","warning"); | |||
return; | |||
} | |||
var fullpath = pathname+(pathname===""?"":"/")+filename; | |||
if (!overwrite) { | |||
//var pathnameParts = pathname.split("/"); | |||
//var exists = false; | |||
//var ds = libraryData; | |||
//for (var pnp in pathnameParts) { | |||
// if (ds.d && pathnameParts[pnp] in ds.d) { | |||
// ds = ds.d[pathnameParts[pnp]]; | |||
// } else { | |||
// ds = null; | |||
// break; | |||
// } | |||
//} | |||
//if (ds && ds.f) { | |||
// for (var f in ds.f) { | |||
// if (ds.f[f].fn == fullpath) { | |||
// exists = true; | |||
// break; | |||
// } | |||
// } | |||
//} | |||
//if (exists) { | |||
// $("#node-dialog-library-save-type").html(options.type); | |||
// $("#node-dialog-library-save-name").html(fullpath); | |||
// $("#node-dialog-library-save-confirm").dialog( "open" ); | |||
// return; | |||
//} | |||
} | |||
var queryArgs = []; | |||
for (var i=0;i<options.fields.length;i++) { | |||
var field = options.fields[i]; | |||
if (field == "name") { | |||
queryArgs.push("name="+encodeURIComponent(name)); | |||
} else { | |||
queryArgs.push(encodeURIComponent(field)+"="+encodeURIComponent($("#node-input-"+field).val())); | |||
} | |||
} | |||
var queryString = queryArgs.join("&"); | |||
var text = options.editor.getText(); | |||
$.post("library/"+options.url+'/'+fullpath+"?"+queryString,text,function() { | |||
RED.notify("Saved "+options.type,"success"); | |||
}); | |||
} | |||
$( "#node-dialog-library-save-confirm" ).dialog({ | |||
title: "Save to library", | |||
modal: true, | |||
autoOpen: false, | |||
width: 530, | |||
height: 230, | |||
buttons: [ | |||
{ | |||
text: "Ok", | |||
click: function() { | |||
saveToLibrary(true); | |||
$( this ).dialog( "close" ); | |||
} | |||
}, | |||
{ | |||
text: "Cancel", | |||
click: function() { | |||
$( this ).dialog( "close" ); | |||
} | |||
} | |||
] | |||
}); | |||
$( "#node-dialog-library-save" ).dialog({ | |||
title: "Save to library", | |||
modal: true, | |||
autoOpen: false, | |||
width: 530, | |||
height: 230, | |||
buttons: [ | |||
{ | |||
text: "Ok", | |||
click: function() { | |||
saveToLibrary(false); | |||
$( this ).dialog( "close" ); | |||
} | |||
}, | |||
{ | |||
text: "Cancel", | |||
click: function() { | |||
$( this ).dialog( "close" ); | |||
} | |||
} | |||
] | |||
}); | |||
} | |||
return { | |||
create: createUI, | |||
loadFlowLibrary: loadFlowLibrary | |||
} | |||
} | |||
return { | |||
create: createUI, | |||
loadFlowLibrary: loadFlowLibrary | |||
} | |||
})(); | |||
@@ -1,4 +1,5 @@ | |||
/** | |||
/** Modified from original Node-Red source, for audio system visualization | |||
* vim: set ts=4: | |||
* Copyright 2013 IBM Corp. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
@@ -14,46 +15,46 @@ | |||
* limitations under the License. | |||
**/ | |||
RED.notify = (function() { | |||
var currentNotifications = []; | |||
var c = 0; | |||
return function(msg,type,fixed,timeout) { | |||
if (currentNotifications.length > 4) { | |||
var ll = currentNotifications.length; | |||
for (var i = 0;ll > 4 && i<currentNotifications.length;i+=1) { | |||
var notifiction = currentNotifications[i]; | |||
if (!notifiction.fixed) { | |||
window.clearTimeout(notifiction.timeoutid); | |||
notifiction.close(); | |||
ll -= 1; | |||
} | |||
} | |||
} | |||
var n = document.createElement("div"); | |||
n.id="red-notification-"+c; | |||
n.className = "alert"; | |||
n.fixed = fixed; | |||
if (type) { | |||
n.className = "alert alert-"+type; | |||
} | |||
n.style.display = "none"; | |||
n.innerHTML = msg; | |||
$("#notifications").append(n); | |||
$(n).slideDown(300); | |||
n.close = (function() { | |||
var nn = n; | |||
return function() { | |||
currentNotifications.splice(currentNotifications.indexOf(nn),1); | |||
$(nn).slideUp(300, function() { | |||
nn.parentNode.removeChild(nn); | |||
}); | |||
}; | |||
})(); | |||
if (!fixed) { | |||
n.timeoutid = window.setTimeout(n.close,timeout||3000); | |||
} | |||
currentNotifications.push(n); | |||
c+=1; | |||
return n; | |||
} | |||
var currentNotifications = []; | |||
var c = 0; | |||
return function(msg,type,fixed,timeout) { | |||
if (currentNotifications.length > 4) { | |||
var ll = currentNotifications.length; | |||
for (var i = 0;ll > 4 && i<currentNotifications.length;i+=1) { | |||
var notifiction = currentNotifications[i]; | |||
if (!notifiction.fixed) { | |||
window.clearTimeout(notifiction.timeoutid); | |||
notifiction.close(); | |||
ll -= 1; | |||
} | |||
} | |||
} | |||
var n = document.createElement("div"); | |||
n.id="red-notification-"+c; | |||
n.className = "alert"; | |||
n.fixed = fixed; | |||
if (type) { | |||
n.className = "alert alert-"+type; | |||
} | |||
n.style.display = "none"; | |||
n.innerHTML = msg; | |||
$("#notifications").append(n); | |||
$(n).slideDown(300); | |||
n.close = (function() { | |||
var nn = n; | |||
return function() { | |||
currentNotifications.splice(currentNotifications.indexOf(nn),1); | |||
$(nn).slideUp(300, function() { | |||
nn.parentNode.removeChild(nn); | |||
}); | |||
}; | |||
})(); | |||
if (!fixed) { | |||
n.timeoutid = window.setTimeout(n.close,timeout||3000); | |||
} | |||
currentNotifications.push(n); | |||
c+=1; | |||
return n; | |||
} | |||
})(); | |||
@@ -17,154 +17,154 @@ | |||
RED.palette = (function() { | |||
var exclusion = ['config','unknown','deprecated']; | |||
var core = ['input', 'output', 'mixer', 'play', 'record', 'synth', 'effect', 'filter', 'analyze']; | |||
function createCategoryContainer(category){ | |||
var exclusion = ['config','unknown','deprecated']; | |||
var core = ['input', 'output', 'mixer', 'play', 'record', 'synth', 'effect', 'filter', 'analyze']; | |||
function createCategoryContainer(category){ | |||
$("#palette-container").append('<div class="palette-category">'+ | |||
'<div id="header-'+category+'" class="palette-header"><i class="expanded icon-chevron-down"></i><span>'+category+'</span></div>'+ | |||
'<div class="palette-content" id="palette-base-category-'+category+'">'+ | |||
'<div id="palette-'+category+'-input"></div>'+ | |||
'<div id="palette-'+category+'-output"></div>'+ | |||
'<div id="palette-'+category+'-function"></div>'+ | |||
'</div>'+ | |||
'</div>'); | |||
} | |||
core.forEach(createCategoryContainer); | |||
function addNodeType(nt,def) { | |||
if ($("#palette_node_"+nt).length) { | |||
return; | |||
} | |||
if (exclusion.indexOf(def.category)===-1) { | |||
var category = def.category.split("-"); | |||
var d = document.createElement("div"); | |||
d.id = "palette_node_"+nt; | |||
d.type = nt; | |||
$("#palette-container").append('<div class="palette-category">'+ | |||
'<div id="header-'+category+'" class="palette-header"><i class="expanded icon-chevron-down"></i><span>'+category+'</span></div>'+ | |||
'<div class="palette-content" id="palette-base-category-'+category+'">'+ | |||
'<div id="palette-'+category+'-input"></div>'+ | |||
'<div id="palette-'+category+'-output"></div>'+ | |||
'<div id="palette-'+category+'-function"></div>'+ | |||
'</div>'+ | |||
'</div>'); | |||
} | |||
core.forEach(createCategoryContainer); | |||
function addNodeType(nt,def) { | |||
if ($("#palette_node_"+nt).length) { | |||
return; | |||
} | |||
if (exclusion.indexOf(def.category)===-1) { | |||
var category = def.category.split("-"); | |||
var d = document.createElement("div"); | |||
d.id = "palette_node_"+nt; | |||
d.type = nt; | |||
//var label = /^(.*?)([ -]in|[ -]out)?$/.exec(nt)[1]; | |||
var label = (def.shortName) ? def.shortName : nt; | |||
//var label = /^(.*?)([ -]in|[ -]out)?$/.exec(nt)[1]; | |||
var label = (def.shortName) ? def.shortName : nt; | |||
d.innerHTML = '<div class="palette_label">'+label+"</div>"; | |||
d.className="palette_node"; | |||
if (def.icon) { | |||
d.style.backgroundImage = "url(icons/"+def.icon+")"; | |||
if (def.align == "right") { | |||
d.style.backgroundPosition = "95% 50%"; | |||
} else if (def.inputs > 0) { | |||
d.style.backgroundPosition = "10% 50%"; | |||
} | |||
} | |||
d.style.backgroundColor = def.color; | |||
if (def.outputs > 0) { | |||
var portOut = document.createElement("div"); | |||
portOut.className = "palette_port palette_port_output"; | |||
d.appendChild(portOut); | |||
} | |||
if (def.inputs > 0) { | |||
var portIn = document.createElement("div"); | |||
portIn.className = "palette_port"; | |||
d.appendChild(portIn); | |||
} | |||
if ($("#palette-base-category-"+category[0]).length === 0){ | |||
createCategoryContainer(category[0]); | |||
} | |||
if ($("#palette-"+def.category).length === 0) { | |||
$("#palette-base-category-"+category[0]).append('<div id="palette-'+def.category+'"></div>'); | |||
} | |||
$("#palette-"+def.category).append(d); | |||
d.onmousedown = function(e) { e.preventDefault(); } | |||
$(d).popover({ | |||
title:d.type, | |||
placement:"right", | |||
trigger: "hover", | |||
delay: { show: 750, hide: 50 }, | |||
html: true, | |||
container:'body', | |||
content: $(($("script[data-help-name|='"+nt+"']").html()||"<p>no information available</p>").trim())[0] | |||
}); | |||
$(d).click(function() { | |||
var help = '<div class="node-help">'+($("script[data-help-name|='"+d.type+"']").html()||"")+"</div>"; | |||
$("#tab-info").html(help); | |||
}); | |||
$(d).draggable({ | |||
helper: 'clone', | |||
appendTo: 'body', | |||
revert: true, | |||
revertDuration: 50 | |||
}); | |||
$("#header-"+category[0]).off('click').on('click', function(e) { | |||
$(this).next().slideToggle(); | |||
$(this).children("i").toggleClass("expanded"); | |||
}); | |||
d.innerHTML = '<div class="palette_label">'+label+"</div>"; | |||
d.className="palette_node"; | |||
if (def.icon) { | |||
d.style.backgroundImage = "url(icons/"+def.icon+")"; | |||
if (def.align == "right") { | |||
d.style.backgroundPosition = "95% 50%"; | |||
} else if (def.inputs > 0) { | |||
d.style.backgroundPosition = "10% 50%"; | |||
} | |||
} | |||
d.style.backgroundColor = def.color; | |||
if (def.outputs > 0) { | |||
var portOut = document.createElement("div"); | |||
portOut.className = "palette_port palette_port_output"; | |||
d.appendChild(portOut); | |||
} | |||
if (def.inputs > 0) { | |||
var portIn = document.createElement("div"); | |||
portIn.className = "palette_port"; | |||
d.appendChild(portIn); | |||
} | |||
if ($("#palette-base-category-"+category[0]).length === 0){ | |||
createCategoryContainer(category[0]); | |||
} | |||
if ($("#palette-"+def.category).length === 0) { | |||
$("#palette-base-category-"+category[0]).append('<div id="palette-'+def.category+'"></div>'); | |||
} | |||
$("#palette-"+def.category).append(d); | |||
d.onmousedown = function(e) { e.preventDefault(); } | |||
$(d).popover({ | |||
title:d.type, | |||
placement:"right", | |||
trigger: "hover", | |||
delay: { show: 750, hide: 50 }, | |||
html: true, | |||
container:'body', | |||
content: $(($("script[data-help-name|='"+nt+"']").html()||"<p>no information available</p>").trim())[0] | |||
}); | |||
$(d).click(function() { | |||
var help = '<div class="node-help">'+($("script[data-help-name|='"+d.type+"']").html()||"")+"</div>"; | |||
$("#tab-info").html(help); | |||
}); | |||
$(d).draggable({ | |||
helper: 'clone', | |||
appendTo: 'body', | |||
revert: true, | |||
revertDuration: 50 | |||
}); | |||
$("#header-"+category[0]).off('click').on('click', function(e) { | |||
$(this).next().slideToggle(); | |||
$(this).children("i").toggleClass("expanded"); | |||
}); | |||
} | |||
} | |||
function removeNodeType(type) { | |||
$("#palette_node_"+type).remove(); | |||
} | |||
function filterChange() { | |||
var val = $("#palette-search-input").val(); | |||
if (val === "") { | |||
$("#palette-search-clear").hide(); | |||
} else { | |||
$("#palette-search-clear").show(); | |||
} | |||
var re = new RegExp(val); | |||
$(".palette_node").each(function(i,el) { | |||
if (val === "" || re.test(el.id)) { | |||
$(this).show(); | |||
} else { | |||
$(this).hide(); | |||
} | |||
}); | |||
} | |||
$("#palette-search-input").focus(function(e) { | |||
RED.keyboard.disable(); | |||
}); | |||
$("#palette-search-input").blur(function(e) { | |||
RED.keyboard.enable(); | |||
}); | |||
$("#palette-search-clear").on("click",function(e) { | |||
e.preventDefault(); | |||
$("#palette-search-input").val(""); | |||
filterChange(); | |||
$("#palette-search-input").focus(); | |||
}); | |||
$("#palette-search-input").val(""); | |||
$("#palette-search-input").on("keyup",function() { | |||
filterChange(); | |||
}); | |||
} | |||
} | |||
function removeNodeType(type) { | |||
$("#palette_node_"+type).remove(); | |||
} | |||
function filterChange() { | |||
var val = $("#palette-search-input").val(); | |||
if (val === "") { | |||
$("#palette-search-clear").hide(); | |||
} else { | |||
$("#palette-search-clear").show(); | |||
} | |||
var re = new RegExp(val); | |||
$(".palette_node").each(function(i,el) { | |||
if (val === "" || re.test(el.id)) { | |||
$(this).show(); | |||
} else { | |||
$(this).hide(); | |||
} | |||
}); | |||
} | |||
$("#palette-search-input").focus(function(e) { | |||
RED.keyboard.disable(); | |||
}); | |||
$("#palette-search-input").blur(function(e) { | |||
RED.keyboard.enable(); | |||
}); | |||
$("#palette-search-clear").on("click",function(e) { | |||
e.preventDefault(); | |||
$("#palette-search-input").val(""); | |||
filterChange(); | |||
$("#palette-search-input").focus(); | |||
}); | |||
$("#palette-search-input").val(""); | |||
$("#palette-search-input").on("keyup",function() { | |||
filterChange(); | |||
}); | |||
$("#palette-search-input").on("focus",function() { | |||
$("body").one("mousedown",function() { | |||
$("#palette-search-input").blur(); | |||
}); | |||
}); | |||
return { | |||
add:addNodeType, | |||
remove:removeNodeType | |||
}; | |||
$("#palette-search-input").on("focus",function() { | |||
$("body").one("mousedown",function() { | |||
$("#palette-search-input").blur(); | |||
}); | |||
}); | |||
return { | |||
add:addNodeType, | |||
remove:removeNodeType | |||
}; | |||
})(); |
@@ -1,4 +1,5 @@ | |||
/** | |||
/** Modified from original Node-Red source, for audio system visualization | |||
* vim: set ts=4: | |||
* Copyright 2013 IBM Corp. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
@@ -15,139 +16,139 @@ | |||
**/ | |||
RED.sidebar = (function() { | |||
//$('#sidebar').tabs(); | |||
var sidebar_tabs = RED.tabs.create({ | |||
id:"sidebar-tabs", | |||
onchange:function(tab) { | |||
$("#sidebar-content").children().hide(); | |||
$("#"+tab.id).show(); | |||
}, | |||
onremove: function(tab) { | |||
$("#"+tab.id).remove(); | |||
} | |||
}); | |||
function addTab(title,content,closeable) { | |||
$("#sidebar-content").append(content); | |||
$(content).hide(); | |||
sidebar_tabs.addTab({id:"tab-"+title,label:title,closeable:closeable}); | |||
//content.style.position = "absolute"; | |||
//$('#sidebar').tabs("refresh"); | |||
} | |||
$('#btn-sidebar').click(function() {toggleSidebar();}); | |||
RED.keyboard.add(/* SPACE */ 32,{ctrl:true},function(){toggleSidebar();d3.event.preventDefault();}); | |||
//$('#sidebar').tabs(); | |||
var sidebar_tabs = RED.tabs.create({ | |||
id:"sidebar-tabs", | |||
onchange:function(tab) { | |||
$("#sidebar-content").children().hide(); | |||
$("#"+tab.id).show(); | |||
}, | |||
onremove: function(tab) { | |||
$("#"+tab.id).remove(); | |||
} | |||
}); | |||
function addTab(title,content,closeable) { | |||
$("#sidebar-content").append(content); | |||
$(content).hide(); | |||
sidebar_tabs.addTab({id:"tab-"+title,label:title,closeable:closeable}); | |||
//content.style.position = "absolute"; | |||
//$('#sidebar').tabs("refresh"); | |||
} | |||
$('#btn-sidebar').click(function() {toggleSidebar();}); | |||
RED.keyboard.add(/* SPACE */ 32,{ctrl:true},function(){toggleSidebar();d3.event.preventDefault();}); | |||
var sidebarSeparator = {}; | |||
$("#sidebar-separator").draggable({ | |||
axis: "x", | |||
start:function(event,ui) { | |||
sidebarSeparator.closing = false; | |||
sidebarSeparator.opening = false; | |||
var winWidth = $(window).width(); | |||
sidebarSeparator.start = ui.position.left; | |||
sidebarSeparator.chartWidth = $("#workspace").width(); | |||
sidebarSeparator.chartRight = winWidth-$("#workspace").width()-$("#workspace").offset().left-2; | |||
var sidebarSeparator = {}; | |||
$("#sidebar-separator").draggable({ | |||
axis: "x", | |||
start:function(event,ui) { | |||
sidebarSeparator.closing = false; | |||
sidebarSeparator.opening = false; | |||
var winWidth = $(window).width(); | |||
sidebarSeparator.start = ui.position.left; | |||
sidebarSeparator.chartWidth = $("#workspace").width(); | |||
sidebarSeparator.chartRight = winWidth-$("#workspace").width()-$("#workspace").offset().left-2; | |||
if (!btnSidebar.hasClass("active")) { | |||
sidebarSeparator.opening = true; | |||
var newChartRight = 15; | |||
$("#sidebar").addClass("closing"); | |||
$("#workspace").css("right",newChartRight); | |||
$("#chart-zoom-controls").css("right",newChartRight+20); | |||
$("#sidebar").width(0); | |||
toggleSidebar(); | |||
RED.view.resize(); | |||
} | |||
if (!btnSidebar.hasClass("active")) { | |||
sidebarSeparator.opening = true; | |||
var newChartRight = 15; | |||
$("#sidebar").addClass("closing"); | |||
$("#workspace").css("right",newChartRight); | |||
$("#chart-zoom-controls").css("right",newChartRight+20); | |||
$("#sidebar").width(0); | |||
toggleSidebar(); | |||
RED.view.resize(); | |||
} | |||
sidebarSeparator.width = $("#sidebar").width(); | |||
}, | |||
drag: function(event,ui) { | |||
var d = ui.position.left-sidebarSeparator.start; | |||
var newSidebarWidth = sidebarSeparator.width-d; | |||
if (sidebarSeparator.opening) { | |||
newSidebarWidth -= 13; | |||
} | |||
if (newSidebarWidth > 150) { | |||
if (sidebarSeparator.chartWidth+d < 200) { | |||
ui.position.left = 200+sidebarSeparator.start-sidebarSeparator.chartWidth; | |||
d = ui.position.left-sidebarSeparator.start; | |||
newSidebarWidth = sidebarSeparator.width-d; | |||
} | |||
} | |||
if (newSidebarWidth < 150) { | |||
if (!sidebarSeparator.closing) { | |||
$("#sidebar").addClass("closing"); | |||
sidebarSeparator.closing = true; | |||
} | |||
if (!sidebarSeparator.opening) { | |||
newSidebarWidth = 150; | |||
ui.position.left = sidebarSeparator.width-(150 - sidebarSeparator.start); | |||
d = ui.position.left-sidebarSeparator.start; | |||
} | |||
} else if (newSidebarWidth > 150 && (sidebarSeparator.closing || sidebarSeparator.opening)) { | |||
sidebarSeparator.closing = false; | |||
$("#sidebar").removeClass("closing"); | |||
} | |||
sidebarSeparator.width = $("#sidebar").width(); | |||
}, | |||
drag: function(event,ui) { | |||
var d = ui.position.left-sidebarSeparator.start; | |||
var newSidebarWidth = sidebarSeparator.width-d; | |||
if (sidebarSeparator.opening) { | |||
newSidebarWidth -= 13; | |||
} | |||
if (newSidebarWidth > 150) { | |||
if (sidebarSeparator.chartWidth+d < 200) { | |||
ui.position.left = 200+sidebarSeparator.start-sidebarSeparator.chartWidth; | |||
d = ui.position.left-sidebarSeparator.start; | |||
newSidebarWidth = sidebarSeparator.width-d; | |||
} | |||
} | |||
if (newSidebarWidth < 150) { | |||
if (!sidebarSeparator.closing) { | |||
$("#sidebar").addClass("closing"); | |||
sidebarSeparator.closing = true; | |||
} | |||
if (!sidebarSeparator.opening) { | |||
newSidebarWidth = 150; | |||
ui.position.left = sidebarSeparator.width-(150 - sidebarSeparator.start); | |||
d = ui.position.left-sidebarSeparator.start; | |||
} | |||
} else if (newSidebarWidth > 150 && (sidebarSeparator.closing || sidebarSeparator.opening)) { | |||
sidebarSeparator.closing = false; | |||
$("#sidebar").removeClass("closing"); | |||
} | |||
var newChartRight = sidebarSeparator.chartRight-d; | |||
$("#workspace").css("right",newChartRight); | |||
$("#chart-zoom-controls").css("right",newChartRight+20); | |||
$("#sidebar").width(newSidebarWidth); | |||
var newChartRight = sidebarSeparator.chartRight-d; | |||
$("#workspace").css("right",newChartRight); | |||
$("#chart-zoom-controls").css("right",newChartRight+20); | |||
$("#sidebar").width(newSidebarWidth); | |||
sidebar_tabs.resize(); | |||
RED.view.resize(); | |||
}, | |||
stop:function(event,ui) { | |||
RED.view.resize(); | |||
if (sidebarSeparator.closing) { | |||
$("#sidebar").removeClass("closing"); | |||
toggleSidebar(); | |||
if ($("#sidebar").width() < 180) { | |||
$("#sidebar").width(180); | |||
$("#workspace").css("right",208); | |||
$("#chart-zoom-controls").css("right",228); | |||
} | |||
} | |||
$("#sidebar-separator").css("left","auto"); | |||
$("#sidebar-separator").css("right",($("#sidebar").width()+13)+"px"); | |||
} | |||
}); | |||
var btnSidebar = $("#btn-sidebar"); | |||
function toggleSidebar() { | |||
//if ($('#sidebar').tabs( "option", "active" ) === false) { | |||
// $('#sidebar').tabs( "option", "active",0); | |||
//} | |||
btnSidebar.toggleClass("active"); | |||
if (!btnSidebar.hasClass("active")) { | |||
$("#main-container").addClass("sidebar-closed"); | |||
} else { | |||
$("#main-container").removeClass("sidebar-closed"); | |||
} | |||
} | |||
toggleSidebar(); | |||
function showSidebar(id) { | |||
if (!$("#btn-sidebar").hasClass("active")) { | |||
toggleSidebar(); | |||
} | |||
sidebar_tabs.activateTab("tab-"+id); | |||
} | |||
function containsTab(id) { | |||
return sidebar_tabs.contains("tab-"+id); | |||
} | |||
return { | |||
addTab: addTab, | |||
show: showSidebar, | |||
containsTab: containsTab | |||
} | |||
sidebar_tabs.resize(); | |||
RED.view.resize(); | |||
}, | |||
stop:function(event,ui) { | |||
RED.view.resize(); | |||
if (sidebarSeparator.closing) { | |||
$("#sidebar").removeClass("closing"); | |||
toggleSidebar(); | |||
if ($("#sidebar").width() < 180) { | |||
$("#sidebar").width(180); | |||
$("#workspace").css("right",208); | |||
$("#chart-zoom-controls").css("right",228); | |||
} | |||
} | |||
$("#sidebar-separator").css("left","auto"); | |||
$("#sidebar-separator").css("right",($("#sidebar").width()+13)+"px"); | |||
} | |||
}); | |||
var btnSidebar = $("#btn-sidebar"); | |||
function toggleSidebar() { | |||
//if ($('#sidebar').tabs( "option", "active" ) === false) { | |||
// $('#sidebar').tabs( "option", "active",0); | |||
//} | |||
btnSidebar.toggleClass("active"); | |||
if (!btnSidebar.hasClass("active")) { | |||
$("#main-container").addClass("sidebar-closed"); | |||
} else { | |||
$("#main-container").removeClass("sidebar-closed"); | |||
} | |||
} | |||
toggleSidebar(); | |||
function showSidebar(id) { | |||
if (!$("#btn-sidebar").hasClass("active")) { | |||
toggleSidebar(); | |||
} | |||
sidebar_tabs.activateTab("tab-"+id); | |||
} | |||
function containsTab(id) { | |||
return sidebar_tabs.contains("tab-"+id); | |||
} | |||
return { | |||
addTab: addTab, | |||
show: showSidebar, | |||
containsTab: containsTab | |||
} | |||
})(); |
@@ -1,4 +1,5 @@ | |||
/** | |||
/** Modified from original Node-Red source, for audio system visualization | |||
* vim: set ts=4: | |||
* Copyright 2013 IBM Corp. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
@@ -14,13 +15,13 @@ | |||
* limitations under the License. | |||
**/ | |||
RED.state = { | |||
DEFAULT: 0, | |||
MOVING: 1, | |||
JOINING: 2, | |||
MOVING_ACTIVE: 3, | |||
ADDING: 4, | |||
EDITING: 5, | |||
EXPORT: 6, | |||
IMPORT: 7, | |||
IMPORT_DRAGGING: 8 | |||
DEFAULT: 0, | |||
MOVING: 1, | |||
JOINING: 2, | |||
MOVING_ACTIVE: 3, | |||
ADDING: 4, | |||
EDITING: 5, | |||
EXPORT: 6, | |||
IMPORT: 7, | |||
IMPORT_DRAGGING: 8 | |||
} |
@@ -1,4 +1,5 @@ | |||
/** | |||
/** Modified from original Node-Red source, for audio system visualization | |||
* vim: set ts=4: | |||
* Copyright 2013 IBM Corp. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
@@ -14,70 +15,70 @@ | |||
* limitations under the License. | |||
**/ | |||
RED.sidebar.config = (function() { | |||
var content = document.createElement("div"); | |||
content.id = "tab-config"; | |||
content.style.paddingTop = "4px"; | |||
content.style.paddingLeft = "4px"; | |||
content.style.paddingRight = "4px"; | |||
var list = $("<ul>",{class:"tab-config-list"}).appendTo(content); | |||
$("#btn-config-nodes").click(function(){ | |||
if (!RED.sidebar.containsTab("config")) { | |||
RED.sidebar.addTab("config",content,true); | |||
} | |||
refresh(); | |||
RED.sidebar.show("config"); | |||
}); | |||
function refresh() { | |||
list.empty(); | |||
RED.nodes.eachConfig(function(node) { | |||
var li = list.find("#tab-config-list-type-"+node.type); | |||
if (li.length === 0) { | |||
li = $("<li>",{id:"tab-config-list-type-"+node.type}).appendTo(list); | |||
$('<div class="tab-config-list-type">'+node.type+'</div>').appendTo(li); | |||
} | |||
var label = ""; | |||
if (typeof node._def.label == "function") { | |||
label = node._def.label.call(node); | |||
} else { | |||
label = node._def.label; | |||
} | |||
label = label || " "; | |||
var entry = $('<div class="tab-config-list-entry"></div>').appendTo(li); | |||
entry.on('dblclick',function(e) { | |||
RED.editor.editConfig("", node.type, node.id); | |||
}); | |||
var userArray = node.users.map(function(n) { return n.id }); | |||
entry.on('mouseover',function(e) { | |||
RED.nodes.eachNode(function(node) { | |||
if( userArray.indexOf(node.id) != -1) { | |||
node.highlighted = true; | |||
node.dirty = true; | |||
} | |||
}); | |||
RED.view.redraw(); | |||
}); | |||
var content = document.createElement("div"); | |||
content.id = "tab-config"; | |||
content.style.paddingTop = "4px"; | |||
content.style.paddingLeft = "4px"; | |||
content.style.paddingRight = "4px"; | |||
var list = $("<ul>",{class:"tab-config-list"}).appendTo(content); | |||
$("#btn-config-nodes").click(function(){ | |||
if (!RED.sidebar.containsTab("config")) { | |||
RED.sidebar.addTab("config",content,true); | |||
} | |||
refresh(); | |||
RED.sidebar.show("config"); | |||
}); | |||
function refresh() { | |||
list.empty(); | |||
RED.nodes.eachConfig(function(node) { | |||
var li = list.find("#tab-config-list-type-"+node.type); | |||
if (li.length === 0) { | |||
li = $("<li>",{id:"tab-config-list-type-"+node.type}).appendTo(list); | |||
$('<div class="tab-config-list-type">'+node.type+'</div>').appendTo(li); | |||
} | |||
var label = ""; | |||
if (typeof node._def.label == "function") { | |||
label = node._def.label.call(node); | |||
} else { | |||
label = node._def.label; | |||
} | |||
label = label || " "; | |||
var entry = $('<div class="tab-config-list-entry"></div>').appendTo(li); | |||
entry.on('dblclick',function(e) { | |||
RED.editor.editConfig("", node.type, node.id); | |||
}); | |||
var userArray = node.users.map(function(n) { return n.id }); | |||
entry.on('mouseover',function(e) { | |||
RED.nodes.eachNode(function(node) { | |||
if( userArray.indexOf(node.id) != -1) { | |||
node.highlighted = true; | |||
node.dirty = true; | |||
} | |||
}); | |||
RED.view.redraw(); | |||
}); | |||
entry.on('mouseout',function(e) { | |||
RED.nodes.eachNode(function(node) { | |||
if(node.highlighted) { | |||
node.highlighted = false; | |||
node.dirty = true; | |||
} | |||
}); | |||
RED.view.redraw(); | |||
}); | |||
$('<div class="tab-config-list-label">'+label+'</div>').appendTo(entry); | |||
$('<div class="tab-config-list-users">'+node.users.length+'</div>').appendTo(entry); | |||
}); | |||
} | |||
return { | |||
refresh:refresh | |||
} | |||
entry.on('mouseout',function(e) { | |||
RED.nodes.eachNode(function(node) { | |||
if(node.highlighted) { | |||
node.highlighted = false; | |||
node.dirty = true; | |||
} | |||
}); | |||
RED.view.redraw(); | |||
}); | |||
$('<div class="tab-config-list-label">'+label+'</div>').appendTo(entry); | |||
$('<div class="tab-config-list-users">'+node.users.length+'</div>').appendTo(entry); | |||
}); | |||
} | |||
return { | |||
refresh:refresh | |||
} | |||
})(); |
@@ -1,4 +1,5 @@ | |||
/** | |||
/** Modified from original Node-Red source, for audio system visualization | |||
* vim: set ts=4: | |||
* Copyright 2013 IBM Corp. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
@@ -14,76 +15,76 @@ | |||
* limitations under the License. | |||
**/ | |||
RED.sidebar.info = (function() { | |||
var content = document.createElement("div"); | |||
content.id = "tab-info"; | |||
content.style.paddingTop = "4px"; | |||
content.style.paddingLeft = "4px"; | |||
content.style.paddingRight = "4px"; | |||
var content = document.createElement("div"); | |||
content.id = "tab-info"; | |||
content.style.paddingTop = "4px"; | |||
content.style.paddingLeft = "4px"; | |||
content.style.paddingRight = "4px"; | |||
RED.sidebar.addTab("info",content); | |||
function jsonFilter(key,value) { | |||
if (key === "") { | |||
return value; | |||
} | |||
var t = typeof value; | |||
if ($.isArray(value)) { | |||
return "[array:"+value.length+"]"; | |||
} else if (t === "object") { | |||
return "[object]" | |||
} else if (t === "string") { | |||
if (value.length > 30) { | |||
return value.substring(0,30)+" ..."; | |||
} | |||
} | |||
return value; | |||
} | |||
function refresh(node) { | |||
var table = '<table class="node-info"><tbody>'; | |||
RED.sidebar.addTab("info",content); | |||
function jsonFilter(key,value) { | |||
if (key === "") { | |||
return value; | |||
} | |||
var t = typeof value; | |||
if ($.isArray(value)) { | |||
return "[array:"+value.length+"]"; | |||
} else if (t === "object") { | |||
return "[object]" | |||
} else if (t === "string") { | |||
if (value.length > 30) { | |||
return value.substring(0,30)+" ..."; | |||
} | |||
} | |||
return value; | |||
} | |||
function refresh(node) { | |||
var table = '<table class="node-info"><tbody>'; | |||
table += "<tr><td>Type</td><td> "+node.type+"</td></tr>"; | |||
table += "<tr><td>ID</td><td> "+node.id+"</td></tr>"; | |||
table += '<tr class="blank"><td colspan="2"> Properties</td></tr>'; | |||
for (var n in node._def.defaults) { | |||
if (node._def.defaults.hasOwnProperty(n)) { | |||
var val = node[n]||""; | |||
var type = typeof val; | |||
if (type === "string") { | |||
if (val.length > 30) { | |||
val = val.substring(0,30)+" ..."; | |||
} | |||
val = val.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"); | |||
} else if (type === "number") { | |||
val = val.toString(); | |||
} else if ($.isArray(val)) { | |||
val = "[<br/>"; | |||
for (var i=0;i<Math.min(node[n].length,10);i++) { | |||
var vv = JSON.stringify(node[n][i],jsonFilter," ").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"); | |||
val += " "+i+": "+vv+"<br/>"; | |||
} | |||
if (node[n].length > 10) { | |||
val += " ... "+node[n].length+" items<br/>"; | |||
} | |||
val += "]"; | |||
} else { | |||
val = JSON.stringify(val,jsonFilter," "); | |||
val = val.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"); | |||
} | |||
table += "<tr><td> "+n+"</td><td>"+val+"</td></tr>"; | |||
} | |||
} | |||
table += "</tbody></table><br/>"; | |||
table += '<div class="node-help">'+($("script[data-help-name|='"+node.type+"']").html()||"")+"</div>"; | |||
$("#tab-info").html(table); | |||
} | |||
return { | |||
refresh:refresh, | |||
clear: function() { | |||
$("#tab-info").html(""); | |||
} | |||
} | |||
table += "<tr><td>Type</td><td> "+node.type+"</td></tr>"; | |||
table += "<tr><td>ID</td><td> "+node.id+"</td></tr>"; | |||
table += '<tr class="blank"><td colspan="2"> Properties</td></tr>'; | |||
for (var n in node._def.defaults) { | |||
if (node._def.defaults.hasOwnProperty(n)) { | |||
var val = node[n]||""; | |||
var type = typeof val; | |||
if (type === "string") { | |||
if (val.length > 30) { | |||
val = val.substring(0,30)+" ..."; | |||
} | |||
val = val.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"); | |||
} else if (type === "number") { | |||
val = val.toString(); | |||
} else if ($.isArray(val)) { | |||
val = "[<br/>"; | |||
for (var i=0;i<Math.min(node[n].length,10);i++) { | |||
var vv = JSON.stringify(node[n][i],jsonFilter," ").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"); | |||
val += " "+i+": "+vv+"<br/>"; | |||
} | |||
if (node[n].length > 10) { | |||
val += " ... "+node[n].length+" items<br/>"; | |||
} | |||
val += "]"; | |||
} else { | |||
val = JSON.stringify(val,jsonFilter," "); | |||
val = val.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"); | |||
} | |||
table += "<tr><td> "+n+"</td><td>"+val+"</td></tr>"; | |||
} | |||
} | |||
table += "</tbody></table><br/>"; | |||
table += '<div class="node-help">'+($("script[data-help-name|='"+node.type+"']").html()||"")+"</div>"; | |||
$("#tab-info").html(table); | |||
} | |||
return { | |||
refresh:refresh, | |||
clear: function() { | |||
$("#tab-info").html(""); | |||
} | |||
} | |||
})(); |
@@ -1,4 +1,5 @@ | |||
/** | |||
/** Modified from original Node-Red source, for audio system visualization | |||
* vim: set ts=4: | |||
* Copyright 2013 IBM Corp. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
@@ -17,111 +18,111 @@ | |||
RED.tabs = (function() { | |||
function createTabs(options) { | |||
var tabs = {}; | |||
var ul = $("#"+options.id) | |||
ul.addClass("red-ui-tabs"); | |||
ul.children().first().addClass("active"); | |||
ul.children().addClass("red-ui-tab"); | |||
function onTabClick() { | |||
activateTab($(this)); | |||
return false; | |||
} | |||
function onTabDblClick() { | |||
if (options.ondblclick) { | |||
options.ondblclick(tabs[$(this).attr('href').slice(1)]); | |||
} | |||
return false; | |||
} | |||
function activateTab(link) { | |||
if (typeof link === "string") { | |||
link = ul.find("a[href='#"+link+"']"); | |||
} | |||
if (!link.parent().hasClass("active")) { | |||
ul.children().removeClass("active"); | |||
link.parent().addClass("active"); | |||
if (options.onchange) { | |||
options.onchange(tabs[link.attr('href').slice(1)]); | |||
} | |||
} | |||
} | |||
function updateTabWidths() { | |||
var tabs = ul.find("li.red-ui-tab"); | |||
var width = ul.width(); | |||
var tabCount = tabs.size(); | |||
var tabWidth = (width-6-(tabCount*7))/tabCount; | |||
var pct = 100*tabWidth/width; | |||
tabs.css({width:pct+"%"}); | |||
} | |||
ul.find("li.red-ui-tab a").on("click",onTabClick).on("dblclick",onTabDblClick); | |||
updateTabWidths(); | |||
function removeTab(id) { | |||
var li = ul.find("a[href='#"+id+"']").parent(); | |||
if (li.hasClass("active")) { | |||
var tab = li.prev(); | |||
if (tab.size() === 0) { | |||
tab = li.next(); | |||
} | |||
activateTab(tab.find("a")); | |||
} | |||
li.remove(); | |||
if (options.onremove) { | |||
options.onremove(tabs[id]); | |||
} | |||
delete tabs[id]; | |||
updateTabWidths(); | |||
} | |||
return { | |||
addTab: function(tab) { | |||
tabs[tab.id] = tab; | |||
var li = $("<li/>",{class:"red-ui-tab"}).appendTo(ul); | |||
var link = $("<a/>",{href:"#"+tab.id, class:"red-ui-tab-label"}).appendTo(li); | |||
link.html(tab.label); | |||
link.on("click",onTabClick); | |||
link.on("dblclick",onTabDblClick); | |||
if (tab.closeable) { | |||
var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close"}).appendTo(li); | |||
closeLink.html('<i class="icon-remove" />'); | |||
closeLink.on("click",function(event) { | |||
removeTab(tab.id); | |||
}); | |||
} | |||
updateTabWidths(); | |||
if (options.onadd) { | |||
options.onadd(tab); | |||
} | |||
link.attr("title",tab.label); | |||
if (ul.find("li.red-ui-tab").size() == 1) { | |||
activateTab(link); | |||
} | |||
}, | |||
removeTab: removeTab, | |||
activateTab: activateTab, | |||
resize: updateTabWidths, | |||
count: function() { | |||
return ul.find("li.red-ui-tab").size(); | |||
}, | |||
contains: function(id) { | |||
return ul.find("a[href='#"+id+"']").length > 0; | |||
} | |||
function createTabs(options) { | |||
var tabs = {}; | |||
var ul = $("#"+options.id) | |||
ul.addClass("red-ui-tabs"); | |||
ul.children().first().addClass("active"); | |||
ul.children().addClass("red-ui-tab"); | |||
function onTabClick() { | |||
activateTab($(this)); | |||
return false; | |||
} | |||
function onTabDblClick() { | |||
if (options.ondblclick) { | |||
options.ondblclick(tabs[$(this).attr('href').slice(1)]); | |||
} | |||
return false; | |||
} | |||
function activateTab(link) { | |||
if (typeof link === "string") { | |||
link = ul.find("a[href='#"+link+"']"); | |||
} | |||
if (!link.parent().hasClass("active")) { | |||
ul.children().removeClass("active"); | |||
link.parent().addClass("active"); | |||
if (options.onchange) { | |||
options.onchange(tabs[link.attr('href').slice(1)]); | |||
} | |||
} | |||
} | |||
function updateTabWidths() { | |||
var tabs = ul.find("li.red-ui-tab"); | |||
var width = ul.width(); | |||
var tabCount = tabs.size(); | |||
var tabWidth = (width-6-(tabCount*7))/tabCount; | |||
var pct = 100*tabWidth/width; | |||
tabs.css({width:pct+"%"}); | |||
} | |||
ul.find("li.red-ui-tab a").on("click",onTabClick).on("dblclick",onTabDblClick); | |||
updateTabWidths(); | |||
function removeTab(id) { | |||
var li = ul.find("a[href='#"+id+"']").parent(); | |||
if (li.hasClass("active")) { | |||
var tab = li.prev(); | |||
if (tab.size() === 0) { | |||
tab = li.next(); | |||
} | |||
activateTab(tab.find("a")); | |||
} | |||
li.remove(); | |||
if (options.onremove) { | |||
options.onremove(tabs[id]); | |||
} | |||
delete tabs[id]; | |||
updateTabWidths(); | |||
} | |||
return { | |||
addTab: function(tab) { | |||
tabs[tab.id] = tab; | |||
var li = $("<li/>",{class:"red-ui-tab"}).appendTo(ul); | |||
var link = $("<a/>",{href:"#"+tab.id, class:"red-ui-tab-label"}).appendTo(li); | |||
link.html(tab.label); | |||
link.on("click",onTabClick); | |||
link.on("dblclick",onTabDblClick); | |||
if (tab.closeable) { | |||
var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close"}).appendTo(li); | |||
closeLink.html('<i class="icon-remove" />'); | |||
closeLink.on("click",function(event) { | |||
removeTab(tab.id); | |||
}); | |||
} | |||
updateTabWidths(); | |||
if (options.onadd) { | |||
options.onadd(tab); | |||
} | |||
link.attr("title",tab.label); | |||
if (ul.find("li.red-ui-tab").size() == 1) { | |||
activateTab(link); | |||
} | |||
}, | |||
removeTab: removeTab, | |||
activateTab: activateTab, | |||
resize: updateTabWidths, | |||
count: function() { | |||
return ul.find("li.red-ui-tab").size(); | |||
}, | |||
contains: function(id) { | |||
return ul.find("a[href='#"+id+"']").length > 0; | |||
} | |||
} | |||
} | |||
return { | |||
create: createTabs | |||
} | |||
} | |||
} | |||
return { | |||
create: createTabs | |||
} | |||
})(); |
@@ -1,4 +1,5 @@ | |||
/** | |||
/** Modified from original Node-Red source, for audio system visualization | |||
* vim: set ts=4: | |||
* Copyright 2014 IBM Corp. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
@@ -16,171 +17,171 @@ | |||
RED.touch = RED.touch||{}; | |||
RED.touch.radialMenu = (function() { | |||
var touchMenu = null; | |||
var isActive = false; | |||
var isOutside = false; | |||
var activeOption = null; | |||
var touchMenu = null; | |||
var isActive = false; | |||
var isOutside = false; | |||
var activeOption = null; | |||
function createRadial(obj,pos,options) { | |||
isActive = true; | |||
try { | |||
var w = $("body").width(); | |||
var h = $("body").height(); | |||
touchMenu = d3.select("body").append("div") | |||
.style({ | |||
position:"absolute", | |||
top: 0, | |||
left:0, | |||
bottom:0, | |||
right:0, | |||
"z-index": 1000 | |||
}) | |||
.on('touchstart',function() { | |||
hide(); | |||
d3.event.preventDefault(); | |||
}); | |||
function createRadial(obj,pos,options) { | |||
isActive = true; | |||
try { | |||
var w = $("body").width(); | |||
var h = $("body").height(); | |||
touchMenu = d3.select("body").append("div") | |||
.style({ | |||
position:"absolute", | |||
top: 0, | |||
left:0, | |||
bottom:0, | |||
right:0, | |||
"z-index": 1000 | |||
}) | |||
.on('touchstart',function() { | |||
hide(); | |||
d3.event.preventDefault(); | |||
}); | |||
var menu = touchMenu.append("div") | |||
.style({ | |||
position: "absolute", | |||
top: (pos[1]-80)+"px", | |||
left:(pos[0]-80)+"px", | |||
"border-radius": "80px", | |||
width: "160px", | |||
height: "160px", | |||
background: "rgba(255,255,255,0.6)", | |||
border: "1px solid #666" | |||
}); | |||
var menuOpts = []; | |||
var createMenuOpt = function(x,y,opt) { | |||
opt.el = menu.append("div") | |||
.style({ | |||
position: "absolute", | |||
top: (y+80-25)+"px", | |||
left:(x+80-25)+"px", | |||
"border-radius": "20px", | |||
width: "50px", | |||
height: "50px", | |||
background: "#fff", | |||
border: "2px solid #666", | |||
"text-align": "center", | |||
"line-height":"50px" | |||
}); | |||
if (opt.icon) { | |||
opt.el.append("i").attr("class","icon "+opt.icon) | |||
} else { | |||
opt.el.html(opt.name); | |||
} | |||
if (opt.disabled) { | |||
opt.el.style({"border-color":"#ccc",color:"#ccc"}); | |||
} | |||
opt.x = x; | |||
opt.y = y; | |||
menuOpts.push(opt); | |||
opt.el.on('touchstart',function() { | |||
opt.el.style("background","#999"); | |||
d3.event.preventDefault(); | |||
d3.event.stopPropagation(); | |||
}); | |||
opt.el.on('touchend',function() { | |||
hide(); | |||
opt.onselect(); | |||
d3.event.preventDefault(); | |||
d3.event.stopPropagation(); | |||
}); | |||
} | |||
var n = options.length; | |||
var dang = Math.max(Math.PI/(n-1),Math.PI/4); | |||
var ang = Math.PI; | |||
for (var i=0;i<n;i++) { | |||
var x = Math.floor(Math.cos(ang)*80); | |||
var y = Math.floor(Math.sin(ang)*80); | |||
if (options[i].name) { | |||
createMenuOpt(x,y,options[i]); | |||
} | |||
ang += dang; | |||
} | |||
var menu = touchMenu.append("div") | |||
.style({ | |||
position: "absolute", | |||
top: (pos[1]-80)+"px", | |||
left:(pos[0]-80)+"px", | |||
"border-radius": "80px", | |||
width: "160px", | |||
height: "160px", | |||
background: "rgba(255,255,255,0.6)", | |||
border: "1px solid #666" | |||
}); | |||
var menuOpts = []; | |||
var createMenuOpt = function(x,y,opt) { | |||
opt.el = menu.append("div") | |||
.style({ | |||
position: "absolute", | |||
top: (y+80-25)+"px", | |||
left:(x+80-25)+"px", | |||
"border-radius": "20px", | |||
width: "50px", | |||
height: "50px", | |||
background: "#fff", | |||
border: "2px solid #666", | |||
"text-align": "center", | |||
"line-height":"50px" | |||
}); | |||
if (opt.icon) { | |||
opt.el.append("i").attr("class","icon "+opt.icon) | |||
} else { | |||
opt.el.html(opt.name); | |||
} | |||
if (opt.disabled) { | |||
opt.el.style({"border-color":"#ccc",color:"#ccc"}); | |||
} | |||
opt.x = x; | |||
opt.y = y; | |||
menuOpts.push(opt); | |||
opt.el.on('touchstart',function() { | |||
opt.el.style("background","#999"); | |||
d3.event.preventDefault(); | |||
d3.event.stopPropagation(); | |||
}); | |||
opt.el.on('touchend',function() { | |||
hide(); | |||
opt.onselect(); | |||
d3.event.preventDefault(); | |||
d3.event.stopPropagation(); | |||
}); | |||
} | |||
var n = options.length; | |||
var dang = Math.max(Math.PI/(n-1),Math.PI/4); | |||
var ang = Math.PI; | |||
for (var i=0;i<n;i++) { | |||
var x = Math.floor(Math.cos(ang)*80); | |||
var y = Math.floor(Math.sin(ang)*80); | |||
if (options[i].name) { | |||
createMenuOpt(x,y,options[i]); | |||
} | |||
ang += dang; | |||
} | |||
var hide = function() { | |||
isActive = false; | |||
activeOption = null; | |||
touchMenu.remove(); | |||
touchMenu = null; | |||
} | |||
obj.on('touchend.radial',function() { | |||
obj.on('touchend.radial',null); | |||
obj.on('touchmenu.radial',null); | |||
if (activeOption) { | |||
try { | |||
activeOption.onselect(); | |||
} catch(err) { | |||
RED._debug(err); | |||
} | |||
hide(); | |||
} else if (isOutside) { | |||
hide(); | |||
} | |||
}); | |||
var hide = function() { | |||
isActive = false; | |||
activeOption = null; | |||
touchMenu.remove(); | |||
touchMenu = null; | |||
} | |||
obj.on('touchend.radial',function() { | |||
obj.on('touchend.radial',null); | |||
obj.on('touchmenu.radial',null); | |||
if (activeOption) { | |||
try { | |||
activeOption.onselect(); | |||
} catch(err) { | |||
RED._debug(err); | |||
} | |||
hide(); | |||
} else if (isOutside) { | |||
hide(); | |||
} | |||
}); | |||
obj.on('touchmove.radial',function() { | |||
try { | |||
var touch0 = d3.event.touches.item(0); | |||
var p = [touch0.pageX - pos[0],touch0.pageY-pos[1]]; | |||
for (var i=0;i<menuOpts.length;i++) { | |||
var opt = menuOpts[i]; | |||
if (!opt.disabled) { | |||
if (p[0]>opt.x-30 && p[0]<opt.x+30 && p[1]>opt.y-30 && p[1]<opt.y+30) { | |||
if (opt !== activeOption) { | |||
opt.el.style("background","#999"); | |||
activeOption = opt; | |||
} | |||
} else if (opt === activeOption) { | |||
opt.el.style("background","#fff"); | |||
activeOption = null; | |||
} else { | |||
opt.el.style("background","#fff"); | |||
} | |||
} | |||
} | |||
if (!activeOption) { | |||
var d = Math.abs((p[0]*p[0])+(p[1]*p[1])); | |||
isOutside = (d > 80*80); | |||
} | |||
} catch(err) { | |||
RED._debug(err); | |||
} | |||
obj.on('touchmove.radial',function() { | |||
try { | |||
var touch0 = d3.event.touches.item(0); | |||
var p = [touch0.pageX - pos[0],touch0.pageY-pos[1]]; | |||
for (var i=0;i<menuOpts.length;i++) { | |||
var opt = menuOpts[i]; | |||
if (!opt.disabled) { | |||
if (p[0]>opt.x-30 && p[0]<opt.x+30 && p[1]>opt.y-30 && p[1]<opt.y+30) { | |||
if (opt !== activeOption) { | |||
opt.el.style("background","#999"); | |||
activeOption = opt; | |||
} | |||
} else if (opt === activeOption) { | |||
opt.el.style("background","#fff"); | |||
activeOption = null; | |||
} else { | |||
opt.el.style("background","#fff"); | |||
} | |||
} | |||
} | |||
if (!activeOption) { | |||
var d = Math.abs((p[0]*p[0])+(p[1]*p[1])); | |||
isOutside = (d > 80*80); | |||
} | |||
} catch(err) { | |||
RED._debug(err); | |||
} | |||
}); | |||
} catch(err) { | |||
RED._debug(err); | |||
} | |||
} | |||
}); | |||
} catch(err) { | |||
RED._debug(err); | |||
} | |||
} | |||
return { | |||
show: createRadial, | |||
active: function() { | |||
return isActive; | |||
} | |||
} | |||
return { | |||
show: createRadial, | |||
active: function() { | |||
return isActive; | |||
} | |||
} | |||
})(); | |||
@@ -1,4 +1,5 @@ | |||
/** | |||
/** Modified from original Node-Red source, for audio system visualization | |||
* vim: set ts=4: | |||
* Copyright 2013 IBM Corp. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
@@ -14,6 +15,6 @@ | |||
* limitations under the License. | |||
**/ | |||
RED.validators = { | |||
number: function(){return function(v) { return v!=='' && !isNaN(v);}}, | |||
regex: function(re){return function(v) { return re.test(v);}} | |||
number: function(){return function(v) { return v!=='' && !isNaN(v);}}, | |||
regex: function(re){return function(v) { return re.test(v);}} | |||
}; |