mirror of
https://github.com/Doodle3D/doodle3d-client.git
synced 2024-11-22 01:07:56 +01:00
Added download GCODE feature, added keyboard shortcuts and added some basic Shapes
This commit is contained in:
parent
dd6c1d8034
commit
b85d3244c9
@ -16,6 +16,9 @@ module.exports = function(grunt) {
|
|||||||
},
|
},
|
||||||
js: {
|
js: {
|
||||||
src: [
|
src: [
|
||||||
|
'js_src/Shape.js',
|
||||||
|
'js_src/Svg.js',
|
||||||
|
'js_src/Keyboard.js',
|
||||||
'js_src/SettingsWindow.js',
|
'js_src/SettingsWindow.js',
|
||||||
'js_src/UpdatePanel.js',
|
'js_src/UpdatePanel.js',
|
||||||
'js_src/PrinterPanel.js',
|
'js_src/PrinterPanel.js',
|
||||||
|
30
js_src/Keyboard.js
Normal file
30
js_src/Keyboard.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
var keyboardShortcutsEnabled = true;
|
||||||
|
|
||||||
|
function initKeyboard() {
|
||||||
|
|
||||||
|
$(document).keypress(function(event) {
|
||||||
|
|
||||||
|
if (!keyboardShortcutsEnabled) return;
|
||||||
|
|
||||||
|
var ch = String.fromCharCode(event.which);
|
||||||
|
|
||||||
|
switch (ch) {
|
||||||
|
case 'c': clearDoodle(); break;
|
||||||
|
case 'p': print(); break;
|
||||||
|
case 'u': oopsUndo(); break;
|
||||||
|
case 'e': settingsWindow.downloadGcode(); break;
|
||||||
|
case 'q': stopPrint(); break;
|
||||||
|
case ',': openSettingsWindow(); break;
|
||||||
|
case 'C': drawCircle(250,180,80,64); break; //x,y,r,res
|
||||||
|
case 'T': drawCircle(250,180,80,3); break; //triangle
|
||||||
|
case 'X': drawCircle(250,180,80,6); break; //hexagon
|
||||||
|
case 'H': previewUp(true); break;
|
||||||
|
case 'h': previewDown(true); break;
|
||||||
|
case '[': previewTwistLeft(); break;
|
||||||
|
case ']': previewTwistRight(); break;
|
||||||
|
case '\'': resetTwist(); break;
|
||||||
|
default: console.log("Key: '" + ch + "' (" + event.which + ")");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
@ -159,6 +159,7 @@ function SettingsWindow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.showSettings = function() {
|
this.showSettings = function() {
|
||||||
|
keyboardShortcutsEnabled = false;
|
||||||
this.loadSettings(function() { // reload settings
|
this.loadSettings(function() { // reload settings
|
||||||
$("#contentOverlay").fadeIn(375, function() {
|
$("#contentOverlay").fadeIn(375, function() {
|
||||||
document.body.removeEventListener('touchmove',prevent,false);
|
document.body.removeEventListener('touchmove',prevent,false);
|
||||||
@ -166,6 +167,7 @@ function SettingsWindow() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.hideSettings = function(complete) {
|
this.hideSettings = function(complete) {
|
||||||
|
keyboardShortcutsEnabled = true;
|
||||||
$("#contentOverlay").fadeOut(375, function() {
|
$("#contentOverlay").fadeOut(375, function() {
|
||||||
document.body.addEventListener('touchmove',prevent,false);
|
document.body.addEventListener('touchmove',prevent,false);
|
||||||
// self.window.css("display","none");
|
// self.window.css("display","none");
|
||||||
@ -366,6 +368,14 @@ function SettingsWindow() {
|
|||||||
window.location.href = self.wifiboxURL + "/info/logfiles"
|
window.location.href = self.wifiboxURL + "/info/logfiles"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.downloadGcode = function() {
|
||||||
|
var gcode = generate_gcode();
|
||||||
|
if (gcode!=undefined) {
|
||||||
|
var blob = new Blob([gcode.join("\n")], {type: "text/plain;charset=utf-8"});
|
||||||
|
saveAs(blob, "doodle3d.gcode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Networks ui
|
* Networks ui
|
||||||
*/
|
*/
|
||||||
|
34
js_src/Shape.js
Normal file
34
js_src/Shape.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
function drawCircle(x0,y0,r,res) {
|
||||||
|
if (res==undefined) res = 50; //circle resolution
|
||||||
|
beginShape();
|
||||||
|
var step=Math.PI * 2.0 / res;
|
||||||
|
for (var a=0; a<=Math.PI*2; a+=step) {
|
||||||
|
var x = Math.sin(a) * r + x0;
|
||||||
|
var y = Math.cos(a) * r + y0;
|
||||||
|
if (a==0) shapeMoveTo(x,y);
|
||||||
|
else shapeLineTo(x,y);
|
||||||
|
}
|
||||||
|
endShape();
|
||||||
|
}
|
||||||
|
|
||||||
|
function beginShape(x,y) {
|
||||||
|
setSketchModified(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function shapeMoveTo(x,y) {
|
||||||
|
_points.push([x, y, true]);
|
||||||
|
adjustBounds(x, y)
|
||||||
|
adjustPreviewTransformation();
|
||||||
|
draw(x, y, .5);
|
||||||
|
}
|
||||||
|
|
||||||
|
function shapeLineTo(x,y) {
|
||||||
|
_points.push([x, y, false]);
|
||||||
|
adjustBounds(x, y)
|
||||||
|
adjustPreviewTransformation();
|
||||||
|
draw(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function endShape() {
|
||||||
|
renderToImageDataPreview();
|
||||||
|
}
|
132
js_src/Svg.js
Normal file
132
js_src/Svg.js
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
//SVG validator: http://validator.w3.org/
|
||||||
|
//SVG viewer: http://svg-edit.googlecode.com/svn/branches/2.6/editor/svg-editor.html
|
||||||
|
function saveToSvg() {
|
||||||
|
var lastX = 0, lastY = 0, lastIsMove;
|
||||||
|
var svg = '';
|
||||||
|
|
||||||
|
var boundsWidth = doodleBounds[2] - doodleBounds[0];
|
||||||
|
var boundsHeight = doodleBounds[3] - doodleBounds[1];
|
||||||
|
|
||||||
|
svg += '<?xml version="1.0" standalone="no"?>\n';
|
||||||
|
svg += '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n';
|
||||||
|
svg += '<svg width="' + boundsWidth + '" height="' + boundsHeight + '" version="1.1" xmlns="http://www.w3.org/2000/svg">\n';
|
||||||
|
svg += '\t<desc>Doodle 3D sketch</desc>\n';
|
||||||
|
|
||||||
|
var data = '';
|
||||||
|
for (var i = 0; i < _points.length; ++i) {
|
||||||
|
var x = _points[i][0], y = _points[i][1], isMove = _points[i][2];
|
||||||
|
var dx = x - lastX, dy = y - lastY;
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
data += 'M'; //emit absolute move on first pair of coordinates
|
||||||
|
else if (isMove != lastIsMove)
|
||||||
|
data += isMove ? 'm' : 'l';
|
||||||
|
|
||||||
|
data += dx + ',' + dy + ' ';
|
||||||
|
|
||||||
|
lastX = x;
|
||||||
|
lastY = y;
|
||||||
|
lastIsMove = isMove;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg += '\t<path transform="translate(' + -doodleBounds[0] + ',' + -doodleBounds[1] + ')" d="' + data + '" fill="none" stroke="black" stroke-width="2" />\n';
|
||||||
|
|
||||||
|
var fields = JSON.stringify({'height': numLayers, 'outlineShape': VERTICALSHAPE, 'twist': rStep});
|
||||||
|
svg += '\t<!--<![CDATA[d3d-keys ' + fields + ']]>-->\n';
|
||||||
|
|
||||||
|
svg += '</svg>\n';
|
||||||
|
|
||||||
|
return svg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: use local variables instead of _points,numLayers,VERTICALSHAPE and rStep so we can leave a current doodle in tact if an error occurs while parsing
|
||||||
|
function loadFromSvg(svgData) {
|
||||||
|
var mode = '', x = 0, y = 0;
|
||||||
|
|
||||||
|
console.log("loading " + svgData.length + " bytes of data...");
|
||||||
|
|
||||||
|
clearDoodle();
|
||||||
|
|
||||||
|
var p = svgData.indexOf("<path");
|
||||||
|
if (p == -1) { console.log("loadFromSvg: could not find parsing start point"); return false; }
|
||||||
|
p = svgData.indexOf('d="', p);
|
||||||
|
if (p == -1) { console.log("loadFromSvg: could not find parsing start point"); return false; }
|
||||||
|
p += 3; //skip 'd="'
|
||||||
|
|
||||||
|
var skipSpace = function() { while (svgData.charAt(p) == ' ') p++; }
|
||||||
|
var parseCommand = function() {
|
||||||
|
while (true) {
|
||||||
|
skipSpace();
|
||||||
|
var c = svgData.charAt(p);
|
||||||
|
if (c == 'M' || c == 'm' || c == 'l') { //new command letter
|
||||||
|
mode = c;
|
||||||
|
} else if (c == '"') { //end of command chain
|
||||||
|
return true;
|
||||||
|
} else { //something else, must be a pair of coordinates...
|
||||||
|
var tx = 0, ty = 0, numberEnd = 0, len = 0;
|
||||||
|
numberEnd = svgData.indexOf(',', p);
|
||||||
|
if (numberEnd == -1) { console.log("could not find comma in coordinate pair"); return false; }
|
||||||
|
len = numberEnd - p;
|
||||||
|
tx = parseInt(svgData.substr(p, len));
|
||||||
|
p += len + 1;
|
||||||
|
skipSpace();
|
||||||
|
numberEnd = svgData.indexOf(' ', p);
|
||||||
|
if (numberEnd == -1) { console.log("could not find space after coordinate pair"); return false; }
|
||||||
|
len = numberEnd - p;
|
||||||
|
ty = parseInt(svgData.substr(p, len));
|
||||||
|
p += len;
|
||||||
|
|
||||||
|
if (mode == 'M' || mode == 'L') {
|
||||||
|
x = tx; y = ty;
|
||||||
|
} else if (mode == 'm' || mode == 'l') {
|
||||||
|
x += tx; y += ty;
|
||||||
|
} else {
|
||||||
|
console.log("loadFromSvg: found coordinate pair but mode was never set");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var isMove = mode == 'm' || mode == 'M';
|
||||||
|
|
||||||
|
//TODO: create script-wide function for adding points?
|
||||||
|
//console.log("inserting "+x+","+y+" ",isMove);
|
||||||
|
updatePrevX = x;
|
||||||
|
updatePrevY = y;
|
||||||
|
_points.push([x, y, isMove]);
|
||||||
|
adjustBounds(x, y);
|
||||||
|
adjustPreviewTransformation();
|
||||||
|
|
||||||
|
if (isMove) draw(x, y, .5);
|
||||||
|
else draw(x, y);
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
parseCommand(); //depends on value of p, so don't move this without taking that into consideration
|
||||||
|
|
||||||
|
const fieldDefMarker = "<!--<![CDATA[d3d-keys";
|
||||||
|
p = svgData.indexOf(fieldDefMarker);
|
||||||
|
if (p == -1) { console.log("loadFromSvg: could not find metadata marker"); return false; }
|
||||||
|
p += fieldDefMarker.length;
|
||||||
|
skipSpace();
|
||||||
|
|
||||||
|
var endP = svgData.indexOf("]]>-->", p);
|
||||||
|
if (endP == -1) { console.log("loadFromSvg: could not find metadata end-marker"); return false; }
|
||||||
|
var metaFields = JSON.parse(svgData.substr(p, endP - p));
|
||||||
|
//TODO: log error and return false if parsing failed
|
||||||
|
for (var k in metaFields) {
|
||||||
|
var v = metaFields[k];
|
||||||
|
switch (k) {
|
||||||
|
case "height": numLayers = v; break;
|
||||||
|
case "outlineShape": VERTICALSHAPE = v; break;
|
||||||
|
case "twist": rStep = v; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderToImageDataPreview();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
@ -246,10 +246,10 @@ function print(e) {
|
|||||||
console.log("sendPrintCommands is false: not sending print command to 3dprinter");
|
console.log("sendPrintCommands is false: not sending print command to 3dprinter");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debugMode) {
|
// if (debugMode) {
|
||||||
$("#textdump").text("");
|
// $("#textdump").text("");
|
||||||
$("#textdump").text(gcode.join("\n"));
|
// $("#textdump").text(gcode.join("\n"));
|
||||||
}
|
// }
|
||||||
|
|
||||||
}, gcodeGenerateDelay);
|
}, gcodeGenerateDelay);
|
||||||
} else {
|
} else {
|
||||||
@ -336,7 +336,11 @@ function previewTwistRight(redrawLess) {
|
|||||||
setSketchModified(true);
|
setSketchModified(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetTwist() {
|
||||||
|
rStep = 0;
|
||||||
|
redrawRenderedPreview();
|
||||||
|
setSketchModified(true);
|
||||||
|
}
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
setState(printer.state,printer.hasControl);
|
setState(printer.state,printer.hasControl);
|
||||||
|
@ -477,136 +477,6 @@ function prevent(e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//SVG validator: http://validator.w3.org/
|
|
||||||
//SVG viewer: http://svg-edit.googlecode.com/svn/branches/2.6/editor/svg-editor.html
|
|
||||||
function saveToSvg() {
|
|
||||||
var lastX = 0, lastY = 0, lastIsMove;
|
|
||||||
var svg = '';
|
|
||||||
|
|
||||||
var boundsWidth = doodleBounds[2] - doodleBounds[0];
|
|
||||||
var boundsHeight = doodleBounds[3] - doodleBounds[1];
|
|
||||||
|
|
||||||
svg += '<?xml version="1.0" standalone="no"?>\n';
|
|
||||||
svg += '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n';
|
|
||||||
svg += '<svg width="' + boundsWidth + '" height="' + boundsHeight + '" version="1.1" xmlns="http://www.w3.org/2000/svg">\n';
|
|
||||||
svg += '\t<desc>Doodle 3D sketch</desc>\n';
|
|
||||||
|
|
||||||
var data = '';
|
|
||||||
for (var i = 0; i < _points.length; ++i) {
|
|
||||||
var x = _points[i][0], y = _points[i][1], isMove = _points[i][2];
|
|
||||||
var dx = x - lastX, dy = y - lastY;
|
|
||||||
|
|
||||||
if (i == 0)
|
|
||||||
data += 'M'; //emit absolute move on first pair of coordinates
|
|
||||||
else if (isMove != lastIsMove)
|
|
||||||
data += isMove ? 'm' : 'l';
|
|
||||||
|
|
||||||
data += dx + ',' + dy + ' ';
|
|
||||||
|
|
||||||
lastX = x;
|
|
||||||
lastY = y;
|
|
||||||
lastIsMove = isMove;
|
|
||||||
}
|
|
||||||
|
|
||||||
svg += '\t<path transform="translate(' + -doodleBounds[0] + ',' + -doodleBounds[1] + ')" d="' + data + '" fill="none" stroke="black" stroke-width="2" />\n';
|
|
||||||
|
|
||||||
var fields = JSON.stringify({'height': numLayers, 'outlineShape': VERTICALSHAPE, 'twist': rStep});
|
|
||||||
svg += '\t<!--<![CDATA[d3d-keys ' + fields + ']]>-->\n';
|
|
||||||
|
|
||||||
svg += '</svg>\n';
|
|
||||||
|
|
||||||
return svg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//TODO: use local variables instead of _points,numLayers,VERTICALSHAPE and rStep so we can leave a current doodle in tact if an error occurs while parsing
|
|
||||||
function loadFromSvg(svgData) {
|
|
||||||
var mode = '', x = 0, y = 0;
|
|
||||||
|
|
||||||
console.log("loading " + svgData.length + " bytes of data...");
|
|
||||||
|
|
||||||
clearDoodle();
|
|
||||||
|
|
||||||
var p = svgData.indexOf("<path");
|
|
||||||
if (p == -1) { console.log("loadFromSvg: could not find parsing start point"); return false; }
|
|
||||||
p = svgData.indexOf('d="', p);
|
|
||||||
if (p == -1) { console.log("loadFromSvg: could not find parsing start point"); return false; }
|
|
||||||
p += 3; //skip 'd="'
|
|
||||||
|
|
||||||
var skipSpace = function() { while (svgData.charAt(p) == ' ') p++; }
|
|
||||||
var parseCommand = function() {
|
|
||||||
while (true) {
|
|
||||||
skipSpace();
|
|
||||||
var c = svgData.charAt(p);
|
|
||||||
if (c == 'M' || c == 'm' || c == 'l') { //new command letter
|
|
||||||
mode = c;
|
|
||||||
} else if (c == '"') { //end of command chain
|
|
||||||
return true;
|
|
||||||
} else { //something else, must be a pair of coordinates...
|
|
||||||
var tx = 0, ty = 0, numberEnd = 0, len = 0;
|
|
||||||
numberEnd = svgData.indexOf(',', p);
|
|
||||||
if (numberEnd == -1) { console.log("could not find comma in coordinate pair"); return false; }
|
|
||||||
len = numberEnd - p;
|
|
||||||
tx = parseInt(svgData.substr(p, len));
|
|
||||||
p += len + 1;
|
|
||||||
skipSpace();
|
|
||||||
numberEnd = svgData.indexOf(' ', p);
|
|
||||||
if (numberEnd == -1) { console.log("could not find space after coordinate pair"); return false; }
|
|
||||||
len = numberEnd - p;
|
|
||||||
ty = parseInt(svgData.substr(p, len));
|
|
||||||
p += len;
|
|
||||||
|
|
||||||
if (mode == 'M' || mode == 'L') {
|
|
||||||
x = tx; y = ty;
|
|
||||||
} else if (mode == 'm' || mode == 'l') {
|
|
||||||
x += tx; y += ty;
|
|
||||||
} else {
|
|
||||||
console.log("loadFromSvg: found coordinate pair but mode was never set");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var isMove = mode == 'm' || mode == 'M';
|
|
||||||
|
|
||||||
//TODO: create script-wide function for adding points?
|
|
||||||
//console.log("inserting "+x+","+y+" ",isMove);
|
|
||||||
updatePrevX = x;
|
|
||||||
updatePrevY = y;
|
|
||||||
_points.push([x, y, isMove]);
|
|
||||||
adjustBounds(x, y);
|
|
||||||
adjustPreviewTransformation();
|
|
||||||
|
|
||||||
if (isMove) draw(x, y, .5);
|
|
||||||
else draw(x, y);
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
parseCommand(); //depends on value of p, so don't move this without taking that into consideration
|
|
||||||
|
|
||||||
const fieldDefMarker = "<!--<![CDATA[d3d-keys";
|
|
||||||
p = svgData.indexOf(fieldDefMarker);
|
|
||||||
if (p == -1) { console.log("loadFromSvg: could not find metadata marker"); return false; }
|
|
||||||
p += fieldDefMarker.length;
|
|
||||||
skipSpace();
|
|
||||||
|
|
||||||
var endP = svgData.indexOf("]]>-->", p);
|
|
||||||
if (endP == -1) { console.log("loadFromSvg: could not find metadata end-marker"); return false; }
|
|
||||||
var metaFields = JSON.parse(svgData.substr(p, endP - p));
|
|
||||||
//TODO: log error and return false if parsing failed
|
|
||||||
for (var k in metaFields) {
|
|
||||||
var v = metaFields[k];
|
|
||||||
switch (k) {
|
|
||||||
case "height": numLayers = v; break;
|
|
||||||
case "outlineShape": VERTICALSHAPE = v; break;
|
|
||||||
case "twist": rStep = v; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderToImageDataPreview();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -25,8 +25,6 @@ var clientInfo = {};
|
|||||||
$(function() {
|
$(function() {
|
||||||
console.log("ready");
|
console.log("ready");
|
||||||
|
|
||||||
//TODO give this a more logical place in code
|
|
||||||
|
|
||||||
if (getURLParameter("d") != "null") debugMode = (getURLParameter("d") == "1");
|
if (getURLParameter("d") != "null") debugMode = (getURLParameter("d") == "1");
|
||||||
if (getURLParameter("p") != "null") sendPrintCommands = (getURLParameter("p") == "1");
|
if (getURLParameter("p") != "null") sendPrintCommands = (getURLParameter("p") == "1");
|
||||||
if (getURLParameter("c") != "null") communicateWithWifibox = (getURLParameter("c") == "1");
|
if (getURLParameter("c") != "null") communicateWithWifibox = (getURLParameter("c") == "1");
|
||||||
@ -59,6 +57,7 @@ $(function() {
|
|||||||
initLayouting();
|
initLayouting();
|
||||||
initSidebars();
|
initSidebars();
|
||||||
initButtonBehavior();
|
initButtonBehavior();
|
||||||
|
initKeyboard();
|
||||||
initVerticalShapes();
|
initVerticalShapes();
|
||||||
if (!clientInfo.isSmartphone) initHelp();
|
if (!clientInfo.isSmartphone) initHelp();
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ var preview_tmp;
|
|||||||
var previewCtx_tmp;
|
var previewCtx_tmp;
|
||||||
|
|
||||||
var previewDefaults = {
|
var previewDefaults = {
|
||||||
rotation: Math.PI/90,
|
rotation: 0, //Math.PI/90,
|
||||||
numLayers: 10
|
numLayers: 10
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="debug_textArea">
|
<div id="debug_textArea">
|
||||||
<textarea rows="5" cols="60" id="textdump"></textarea>
|
<!-- <textarea rows="5" cols="60" id="textdump"></textarea> -->
|
||||||
|
<button onclick="settingsWindow.downloadGcode()">Download gcode</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="debug_display">
|
<div id="debug_display">
|
||||||
</div>
|
</div>
|
||||||
@ -135,6 +136,7 @@
|
|||||||
<!--<script src="../js_src/libs/jquery-joyride-2-1.js"></script>-->
|
<!--<script src="../js_src/libs/jquery-joyride-2-1.js"></script>-->
|
||||||
<script src="js/libs/jquery-joyride-2-1.min.js"></script>
|
<script src="js/libs/jquery-joyride-2-1.min.js"></script>
|
||||||
<script src="js/libs/jquery-coolfieldset.min.js"></script>
|
<script src="js/libs/jquery-coolfieldset.min.js"></script>
|
||||||
|
<script src="js/libs/FileSaver.js"></script>
|
||||||
<!--<script src="js/doodle3d-client.js"></script>-->
|
<!--<script src="js/doodle3d-client.js"></script>-->
|
||||||
<script src="js/doodle3d-client.min.js"></script>
|
<script src="js/doodle3d-client.min.js"></script>
|
||||||
|
|
||||||
|
@ -160,6 +160,7 @@
|
|||||||
<fieldset id="debugPanel">
|
<fieldset id="debugPanel">
|
||||||
<legend>Debug</legend>
|
<legend>Debug</legend>
|
||||||
<input type="button" onclick="settingsWindow.downloadlogs()" name="downloadlogs" value="Download logs" class="button" id="downloadlogs"/>
|
<input type="button" onclick="settingsWindow.downloadlogs()" name="downloadlogs" value="Download logs" class="button" id="downloadlogs"/>
|
||||||
|
<input type="button" onclick="settingsWindow.downloadGcode()" name="downloadGcode" value="Download gcode" class="button" id="downloadGcode"/>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset id="restorePanel">
|
<fieldset id="restorePanel">
|
||||||
<legend>Restore</legend>
|
<legend>Restore</legend>
|
||||||
|
Loading…
Reference in New Issue
Block a user