Просмотр исходного кода

Merge pull request #125 from mamuesp/master

Import function for code from Arduino IDE
dds
Paul Stoffregen 9 лет назад
Родитель
Сommit
7c62476e4f
5 измененных файлов: 176 добавлений и 4 удалений
  1. +9
    -2
      gui/index.html
  2. +1
    -0
      gui/red/main.js
  3. +142
    -0
      gui/red/nodes.js
  4. +9
    -1
      gui/red/storage.js
  5. +15
    -1
      gui/red/ui/view.js

+ 9
- 2
gui/index.html Просмотреть файл

@@ -94,6 +94,7 @@ span.mainfunction {color: #993300; font-weight: bolder}
</div>
<div class="btn-group pull-left">
<a id="btn-deploy" class="btn action-deploy disabled" href="#"><i id="btn-icn-deploy" class="icon-upload"></i>Export</a>
<a id="btn-import" class="btn action-import disabled" href="#"><i id="btn-icn-download" class="icon-download"></i>Import</a>
</div>
</div>
</div>
@@ -276,8 +277,14 @@ span.mainfunction {color: #993300; font-weight: bolder}
</script>
<script type="text/x-red" data-template-name="import-dialog">
<div class="form-row">
<label for="node-input-export"><i class="icon-share"></i>Nodes:</label>
<textarea style="font-family: monospace; font-size: 12px; background:rgb(226, 229, 255); padding-left: 0.5em;" class="input-block-level" id="node-input-import" rows="5" placeholder="Paste nodes here, or lookup in the library"></textarea>
<label for="node-input-import"><i class="icon-share"></i>Nodes:</label>
<textarea style="font-family: monospace; font-size: 12px; background:rgb(226, 229, 255); padding-left: 0.5em;" class="input-block-level" id="node-input-import" rows="5" placeholder="Paste nodes here, or lookup in the library. When importing Arduino code, the whole flow will be replaced."></textarea>
</div>
<div class="form-tips">
<label for="node-input-arduino" style="font-size: 13px; padding: 2px 0px 0px 4px;">
<input style="margin-bottom: 4px; margin-right: 4px;" type="checkbox" id="node-input-arduino" checked="checked" class="input-block-level" />
&nbsp;Import copied code from the Arduino IDE
</label>
</div>
</script>


+ 1
- 0
gui/red/main.js Просмотреть файл

@@ -179,6 +179,7 @@ var RED = (function() {
RED.view.redraw();
setTimeout(function() {
$("#btn-deploy").removeClass("disabled").addClass("btn-danger");
$("#btn-import").removeClass("disabled").addClass("btn-success");
}, 1500);
$('#btn-deploy').click(function() { save(); });
// if the query string has ?info=className, populate info tab

+ 142
- 0
gui/red/nodes.js Просмотреть файл

@@ -306,6 +306,147 @@ RED.nodes = (function() {
return nns;
}

/**
* Parses the input string which contains copied code from the Arduino IDE, scans the
* nodes and connections and forms them into a JSON representation which will be
* returned as string.
*
* So the result may directly imported in the localStorage or the import dialog.
*/
function cppToJSON(newNodesStr) {

var data = "";
var nodes = [];
var cables = [];

const CODE_START = "// GUItool: begin automatically generated code";
const CODE_END = "// GUItool: end automatically generated code";
const NODE_COMMENT = "//";
const NODE_AC = "AudioConnection";
const NODE_AI_I2S = "AudioInputI2S";
const NODE_AM_4 = "AudioMixer4";
const NODE_AC_SGTL = "AudioControlSGTL5000";

var parseLine = function(line) {
var parts = line.match(/^(\S+)\s(.*)/).slice(1);
var type = $.trim(parts[0]);
line = $.trim(parts[1]) + " ";

var description = "";
var coords = [0, 0];
var conn = [];

parts = line.match(/^([^;]{0,});(.*)/);
if (parts) {
parts = parts.slice(1);
description = $.trim(parts[0]);
coords = $.trim(parts[1]);
parts = coords.match(/^([^\/]{0,})\/\/xy=(.*)/);
if (parts) {
parts = parts.slice(1);
coords = $.trim(parts[1]).split(",");
}
}

switch (type) {
case NODE_AC:
parts = description.match(/^([^\(]*\()([^\)]*)(.*)/);
if (parts) {
conn = $.trim(parts[2]).split(",");
cables.push(conn);
}
break;
case NODE_COMMENT:
// do nothing ...
break;
default:
var node = new Object({
"id": description,
"type": type,
"x": parseInt(coords ? coords[0] : 0),
"y": parseInt(coords ? coords[1] : 0),
"z": 0,
"wires": []
});
nodes.push(node);
break;
}
};

var findNode = function(name) {
var len = nodes.length;
for (var key = 0; key < len; key++) {
if (nodes[key].id == name) {
return nodes[key];
}
}
};

var linkCables = function(cables) {
$.each(cables, function(i, item) {
var conn = item;
// when there are only two entries in the array, there
// is only one output to connect to one input, so we have
// to extend the array with the appropriate index "0" for
// both parst (in and out)
if (conn.length == 2) {
conn[2] = conn[1];
conn[1] = conn[3] = 0;
}
// now we assign the outputs (marked by the "idx" of the array)
// to the inputs describend by text
var currNode = findNode($.trim(conn[0]));
var idx = parseInt($.trim(conn[1]));
if (currNode) {
if ($.trim(conn[2]) != "" && $.trim(conn[3]) != "") {
var wire = $.trim(conn[2]) + ":" + $.trim(conn[3]);
var tmp = currNode.wires[idx] ? currNode.wires[idx] : [];
tmp.push(wire);
currNode.wires[idx] = tmp;
}
}
});
};

var traverseLines = function(raw) {
var lines = raw.split("\n");
var useLine = 0;

for (var i = 0; i < lines.length; i++) {
var line = lines[i];
useLine += (line.indexOf(CODE_START) >= 0) ? (useLine ? 0 : 1) : 0;
if (useLine > 0) {
parseLine(line);
}
useLine -= (line.indexOf(CODE_END) >= 0) ? (useLine ? 1 : 0) : 0;
}
};

var readCode = function() {

var fileImport = $("#importInput")[0];
var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.ino|.txt)$/;

if (regex.test(fileImport.value.toLowerCase())) {
if (typeof (FileReader) != "undefined") {
var reader = new FileReader();
$(reader).on("load", function (e) {
});
reader.readAsText(fileImport.files[0]);
} else {
alert("This browser does not support HTML5.");
}
} else {
alert("Please upload a valid INO or text file.");
}
};

traverseLines(newNodesStr);
linkCables(cables);

return JSON.stringify(nodes);
}

function importNodes(newNodesObj,createNewIds) {
try {
var i;
@@ -482,6 +623,7 @@ RED.nodes = (function() {
}
},
node: getNode,
cppToJSON: cppToJSON,
import: importNodes,
refreshValidation: refreshValidation,
getAllFlowNodes: getAllFlowNodes,

+ 9
- 1
gui/red/storage.js Просмотреть файл

@@ -18,8 +18,16 @@ RED.storage = (function() {
if (data) RED.nodes.import(data, false);
}
}
function clear() {
// TOOD: use setTimeout to limit the rate of changes?
if (localStorage) {
localStorage.removeItem("audio_library_guitool");
//console.log("localStorage write");
}
}
return {
update: update,
load: load
load: load,
clear: clear
}
})();

+ 15
- 1
gui/red/ui/view.js Просмотреть файл

@@ -1475,8 +1475,22 @@ RED.view = (function() {
* - attached to mouse for placing - 'IMPORT_DRAGGING'
*/
function importNodes(newNodesStr,touchImport) {
var createNewIds = true;
// TODO: solve this more elegant as the system expects
if ($("#node-input-arduino").prop('checked') === true) {
newNodesStr = RED.nodes.cppToJSON(newNodesStr);
createNewIds = false;
RED.storage.clear();
localStorage.setItem("audio_library_guitool", newNodesStr);
RED.storage.load();
redraw();
return;
}

try {
var result = RED.nodes.import(newNodesStr,true);
var result = RED.nodes.import(newNodesStr,createNewIds);
if (result) {
var new_nodes = result[0];
var new_links = result[1];

Загрузка…
Отмена
Сохранить