remove serial sender. blur input on slice selection
This commit is contained in:
parent
5e1fa70bc5
commit
4b45a31a84
9 changed files with 17 additions and 890 deletions
|
|
@ -1,654 +0,0 @@
|
||||||
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var gs_kiri_serial = exports;
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
if (!self.kiri) return;
|
|
||||||
if (self.kiri.serial) return;
|
|
||||||
|
|
||||||
// tinyg motor (en/dis)able $me / $md
|
|
||||||
// tinyg '%' to flush queue
|
|
||||||
// grbl motor (en/dis)able $1=<ms> (free after ms) $1=255 (always energized)
|
|
||||||
|
|
||||||
var SELF = self,
|
|
||||||
KIRI = SELF.kiri,
|
|
||||||
SPACE = KIRI.space,
|
|
||||||
LOC = SELF.location,
|
|
||||||
SDB = moto.KV,
|
|
||||||
API = kiri.api,
|
|
||||||
initDone = false,
|
|
||||||
nextID = new Date().getTime(),
|
|
||||||
localQueue = [], // buffered command queue
|
|
||||||
localQueueMax = 1500, // max local buffer
|
|
||||||
bounds = null, // bounding box of gcode
|
|
||||||
gcode = null, // gcode buffer
|
|
||||||
gcodeIndex = 0, // gcode buffer send index
|
|
||||||
gcodeAbort = false, // send abort
|
|
||||||
logBuffer = [], // on screen log buffer
|
|
||||||
sendBatchMax = 1000, // max to queue to waiting
|
|
||||||
gcLinesSent, // status of local lines sent
|
|
||||||
gcRemoteQueue, // status of remote queue
|
|
||||||
gcPaused = false, // true if user paused
|
|
||||||
status = null, // machine status
|
|
||||||
socket, // connection to serial sender
|
|
||||||
ports, // list of available ports
|
|
||||||
senderTimeout, // repeating sender call
|
|
||||||
waitingForAck = [], // ids sent to spjs awaiting ack
|
|
||||||
spjsQueueCount = 0, // spjs mem queue size
|
|
||||||
spjsQueueCountMax = 1500, // do not send to spjs over this queue size
|
|
||||||
selectedPort,
|
|
||||||
selectedMode,
|
|
||||||
commandInput,
|
|
||||||
logDiv,
|
|
||||||
jogInput,
|
|
||||||
hostInput,
|
|
||||||
queueInput,
|
|
||||||
connect, // button
|
|
||||||
senderStatus, // machine status
|
|
||||||
senderDialog,
|
|
||||||
senderGcPause, // pause button
|
|
||||||
senderPortClose, // button
|
|
||||||
senderSelectMode, // select dropdown
|
|
||||||
senderSelectPort; // select dropdown
|
|
||||||
|
|
||||||
var init_tinyg = [
|
|
||||||
'{"ej":""}', // enable json
|
|
||||||
'{"js":1}', // json syntax strict
|
|
||||||
'{"sr":n}', // status request
|
|
||||||
'{"sv":1}', // status verbosity filtered
|
|
||||||
'{"si":250}', // status interval 250ms
|
|
||||||
'{"qr":n}', // request queue report
|
|
||||||
'{"qv":1}', // set queue report verbosity
|
|
||||||
'{"ec":0}', // disable LF (from CRLF)
|
|
||||||
'{"jv":4}', // json verbosity 4
|
|
||||||
'{"hp":n}', // get hardware platform
|
|
||||||
'{"fb":n}', // get firmware version
|
|
||||||
'{"mt":n}', // get motor timeout
|
|
||||||
'{"sr":n}',
|
|
||||||
'{"pos":n}' // request position info
|
|
||||||
],
|
|
||||||
init_grbl = [
|
|
||||||
'*init*', // init port
|
|
||||||
'*status*' // request position info
|
|
||||||
];
|
|
||||||
|
|
||||||
KIRI.serial = {
|
|
||||||
setGCode: setGCode,
|
|
||||||
show: show,
|
|
||||||
hide: hide,
|
|
||||||
toggle: toggle,
|
|
||||||
init: init
|
|
||||||
};
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
if (initDone) return;
|
|
||||||
initDone = true;
|
|
||||||
|
|
||||||
var pre = LOC.protocol === 'https:' ? 'wss://' : 'ws://',
|
|
||||||
rpx = $('srxi'),
|
|
||||||
rpy = $('sryi'),
|
|
||||||
rpz = $('srzi'),
|
|
||||||
wpx = $('saxi'),
|
|
||||||
wpy = $('sayi'),
|
|
||||||
wpz = $('sazi'),
|
|
||||||
WCO = {x:0, y:0, z:0},
|
|
||||||
WPOS = {x:0, y:0, z:0},
|
|
||||||
MPOS = {x:0, y:0, z:0};
|
|
||||||
|
|
||||||
senderDialog = $('sender');
|
|
||||||
senderStatus = $('sender-status');
|
|
||||||
commandInput = $('sender-command');
|
|
||||||
logDiv = $('sender-log');
|
|
||||||
jogInput = $('sender-jog');
|
|
||||||
hostInput = $('sender-host');
|
|
||||||
connect = $('sender-connect');
|
|
||||||
gcLinesSent = $('sender-gc-sent');
|
|
||||||
gcRemoteQueue = $('sender-gc-queue');
|
|
||||||
senderSelectMode = $('sender-mode');
|
|
||||||
senderSelectPort = $('sender-port');
|
|
||||||
senderPortClose = $('sender-port-close');
|
|
||||||
senderGcPause = $('sender-gc-pause');
|
|
||||||
|
|
||||||
senderSelectMode.onchange = selectMode;
|
|
||||||
senderSelectPort.onchange = selectPort;
|
|
||||||
senderPortClose.onclick = closePort;
|
|
||||||
senderPortClose.disabled = true;
|
|
||||||
|
|
||||||
$('sender-close').onclick = hide;
|
|
||||||
$('sender-spjs').onclick = function() { window.open("https://wiki.grid.space/wiki/GCode-Sender-in-CAM-Mode", "_help")};
|
|
||||||
$('sjx-').onclick = function() { jog('X',-1) };
|
|
||||||
$('sjx+').onclick = function() { jog('X',1) };
|
|
||||||
$('sjy-').onclick = function() { jog('Y',-1) };
|
|
||||||
$('sjy+').onclick = function() { jog('Y',1) };
|
|
||||||
$('sjz-').onclick = function() { jog('Z',-1) };
|
|
||||||
$('sjz+').onclick = function() { jog('Z',1) };
|
|
||||||
$('sender-set-zero').onclick = function() { sendNow("G92 X0Y0Z0") };
|
|
||||||
$('sender-goto-zero').onclick = function() { sendNow("G90 G0X0Y0Z0") };
|
|
||||||
$('sender-ctrlx').onclick = softReset;
|
|
||||||
$('sender-hold').onclick = feedHold;
|
|
||||||
$('sender-resume').onclick = feedResume;
|
|
||||||
|
|
||||||
$('sender-pad').onmouseover = function() {
|
|
||||||
jogInput.focus();
|
|
||||||
};
|
|
||||||
$('sender-pad').addEventListener('keydown', function(ev) {
|
|
||||||
var dist = (ev.cmdKey ? 0.1 : 1);
|
|
||||||
switch (ev.keyCode) {
|
|
||||||
case 37: // left arrow
|
|
||||||
jog('X', -dist);
|
|
||||||
ev.preventDefault();
|
|
||||||
break;
|
|
||||||
case 39: // right arrow
|
|
||||||
jog('X', dist);
|
|
||||||
ev.preventDefault();
|
|
||||||
break;
|
|
||||||
case 38: // up arrow
|
|
||||||
jog(ev.shiftKey ? 'Z' : 'Y', dist);
|
|
||||||
ev.preventDefault();
|
|
||||||
break;
|
|
||||||
case 40: // down arrow
|
|
||||||
jog(ev.shiftKey ? 'Z' : 'Y', -dist);
|
|
||||||
ev.preventDefault();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('sender-gc-runbox').onclick = runbox;
|
|
||||||
|
|
||||||
$('sender-gc-send').onclick = programStart;
|
|
||||||
senderGcPause.onclick = programPause;
|
|
||||||
$('sender-gc-abort').onclick = programAbort;
|
|
||||||
|
|
||||||
hostInput.value = SDB['kiri-serial'] || '';
|
|
||||||
|
|
||||||
SPACE.onEnterKey([
|
|
||||||
commandInput, function() {
|
|
||||||
if (selectedPort) {
|
|
||||||
sendNow(commandInput.value);
|
|
||||||
emit("» "+commandInput.value);
|
|
||||||
}
|
|
||||||
commandInput.value = '';
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
var handleMessageData = function(dm) {
|
|
||||||
dm = dm.trim();
|
|
||||||
if (dm.charAt(0) === '<') {
|
|
||||||
// grbl status update
|
|
||||||
dm = dm.substring(1,dm.length-2);
|
|
||||||
dm = dm.split('|');
|
|
||||||
// console.log(dm);
|
|
||||||
status = dm.shift();
|
|
||||||
senderStatus.value = status;
|
|
||||||
switch (status) {
|
|
||||||
case 'Idle':
|
|
||||||
case 'Run':
|
|
||||||
case 'Home':
|
|
||||||
case 'Check':
|
|
||||||
senderStatus.style.color = '#080';
|
|
||||||
break;
|
|
||||||
case 'Hold':
|
|
||||||
case 'Door':
|
|
||||||
senderStatus.style.color = '#800';
|
|
||||||
break;
|
|
||||||
case 'Alarm':
|
|
||||||
senderStatus.style.color = '#880';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
var dmt, tt, tv;
|
|
||||||
while (dmt = dm.shift()) {
|
|
||||||
dmt = dmt.split(":");
|
|
||||||
tt = dmt[0];
|
|
||||||
tv = dmt[1].split(",");
|
|
||||||
switch (tt) {
|
|
||||||
case 'MPos':
|
|
||||||
MPOS.x = parseFloat(tv[0]);
|
|
||||||
MPOS.y = parseFloat(tv[1]);
|
|
||||||
MPOS.z = parseFloat(tv[2]);
|
|
||||||
WPOS.x = MPOS.x - WCO.x;
|
|
||||||
WPOS.y = MPOS.y - WCO.y;
|
|
||||||
WPOS.z = MPOS.z - WCO.z;
|
|
||||||
break;
|
|
||||||
case 'WPos':
|
|
||||||
WPOS.x = parseFloat(tv[0]);
|
|
||||||
WPOS.y = parseFloat(tv[1]);
|
|
||||||
WPOS.z = parseFloat(tv[2]);
|
|
||||||
MPOS.x = WPOS.x + WCO.x;
|
|
||||||
MPOS.y = WPOS.y + WCO.y;
|
|
||||||
MPOS.z = WPOS.z + WCO.z;
|
|
||||||
break;
|
|
||||||
case 'WCO':
|
|
||||||
WCO.x = parseFloat(tv[0]);
|
|
||||||
WCO.y = parseFloat(tv[1]);
|
|
||||||
WCO.z = parseFloat(tv[2]);
|
|
||||||
break;
|
|
||||||
case 'FS':
|
|
||||||
break;
|
|
||||||
case 'Ov':
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rpx.value = MPOS.x.toFixed(3);
|
|
||||||
rpy.value = MPOS.y.toFixed(3);
|
|
||||||
rpz.value = MPOS.z.toFixed(3);
|
|
||||||
wpx.value = WPOS.x.toFixed(3);
|
|
||||||
wpy.value = WPOS.y.toFixed(3);
|
|
||||||
wpz.value = WPOS.z.toFixed(3);
|
|
||||||
} else
|
|
||||||
if (dm.charAt(0) === '{') {
|
|
||||||
// tinyg status update
|
|
||||||
dm = js2o(dm);
|
|
||||||
var ro = dm.sr || (dm.r && dm.r.sr ? dm.r.sr : null);
|
|
||||||
if (ro) {
|
|
||||||
if (ro.posx !== undefined) rpx.value = ro.posx;
|
|
||||||
if (ro.posy !== undefined) rpy.value = ro.posy;
|
|
||||||
if (ro.posz !== undefined) rpz.value = ro.posz;
|
|
||||||
}
|
|
||||||
var stat = dm.stat || (dm.r && dm.r.stat ? dm.r.stat : null) || 1;
|
|
||||||
status = ['Unknown','Ready','Alarm','Stop','End','Run','Hold','Probe','Homing'][stat];
|
|
||||||
senderStatus.style.color = ['#000','#080','#880','#000','#000','#000','#800','#000','#000'][stat];
|
|
||||||
senderStatus.value = status;
|
|
||||||
// console.log(dm);
|
|
||||||
} else
|
|
||||||
if (dm && dm !== 'ok') emit("« "+dm);
|
|
||||||
}
|
|
||||||
|
|
||||||
var handleSocketData = function(msg) {
|
|
||||||
var data = msg.data.trim();
|
|
||||||
if (data.charAt(0) === '{') {
|
|
||||||
data = js2o(data);
|
|
||||||
// if (data.Cmd) console.log(data);
|
|
||||||
if (data.Cmd && data.Cmd === 'Queued' && data.Data) {
|
|
||||||
queueAck(data.Data);
|
|
||||||
}
|
|
||||||
if (data.QCnt >= 0) {
|
|
||||||
spjsQueueCount = data.QCnt;
|
|
||||||
gcRemoteQueue.value = spjsQueueCount;
|
|
||||||
}
|
|
||||||
if (data.SerialPorts) updatePortList(data.SerialPorts);
|
|
||||||
if (selectedPort && data.P === selectedPort.Name) {
|
|
||||||
// console.log(data);
|
|
||||||
if (data.D) handleMessageData(data.D);
|
|
||||||
}
|
|
||||||
} else if (data.length > 0) {
|
|
||||||
console.log("** "+data.trim().replace('\n',' ... '));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var onSocketClose = function() {
|
|
||||||
socket = null;
|
|
||||||
connect.innerHTML = 'connect';
|
|
||||||
senderSelectMode.disabled = true;
|
|
||||||
senderSelectPort.disabled = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
connect.onclick = function() {
|
|
||||||
if (socket) {
|
|
||||||
// connect.innerHTML = 'connect';
|
|
||||||
socket.close();
|
|
||||||
socket = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hostInput.value) {
|
|
||||||
return alert('please enter the host:port of your SPJS server');
|
|
||||||
}
|
|
||||||
|
|
||||||
SDB['kiri-serial'] = hostInput.value;
|
|
||||||
|
|
||||||
try {
|
|
||||||
socket = new WebSocket(pre + hostInput.value + "/ws");
|
|
||||||
} catch (e) {
|
|
||||||
emit("** unable to connect to "+hostInput.value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
socket.onopen = function() {
|
|
||||||
emit("** websocket open to "+hostInput.value);
|
|
||||||
socket.send('list');
|
|
||||||
};
|
|
||||||
socket.onerror = function(e) {
|
|
||||||
emit("** socket error with SPJS server @ "+hostInput.value);
|
|
||||||
connect.disabled = false;
|
|
||||||
socket.close();
|
|
||||||
// console.log(e);
|
|
||||||
};
|
|
||||||
socket.onclose = onSocketClose;
|
|
||||||
socket.onmessage = handleSocketData;
|
|
||||||
connect.innerHTML = 'disconnect';
|
|
||||||
connect.disabled = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (socket && ports) {
|
|
||||||
updatePortList(ports);
|
|
||||||
emit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// start sender
|
|
||||||
sender();
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendOpenSequence() {
|
|
||||||
var seq = [];
|
|
||||||
switch (selectedMode) {
|
|
||||||
case 'grbl': seq = init_grbl; break;
|
|
||||||
case 'tinyg': seq = init_tinyg; break;
|
|
||||||
}
|
|
||||||
seq.forEach(function(line) {
|
|
||||||
sendNow(line);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function sender() {
|
|
||||||
// prevent multiple senders
|
|
||||||
if (senderTimeout) return;
|
|
||||||
drainQueue();
|
|
||||||
// setup next call to sender()
|
|
||||||
senderTimeout = setTimeout(function() {
|
|
||||||
senderTimeout = null;
|
|
||||||
sender();
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
function o2js(o) {
|
|
||||||
return JSON.stringify(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
function js2o(s) {
|
|
||||||
try {
|
|
||||||
return JSON.parse(s);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
console.log(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function log(msg) {
|
|
||||||
console.log("serial | "+msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendGcode() {
|
|
||||||
if (gcode) {
|
|
||||||
// timeout and loop at waiting threshold
|
|
||||||
if (waitingForAck.length || localQueue.length > localQueueMax) {
|
|
||||||
setTimeout(sendGcode, 100);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log({
|
|
||||||
gcode: (gcode !== null ? gcode.length : 0),
|
|
||||||
idx: gcodeIndex,
|
|
||||||
waitack: waitingForAck.length,
|
|
||||||
abort: gcodeAbort
|
|
||||||
});
|
|
||||||
// queue up 500 more
|
|
||||||
while (gcodeIndex < gcode.length && !gcodeAbort) {
|
|
||||||
sendToQueue(gcode[gcodeIndex++]);
|
|
||||||
// drain queue every 500 lines
|
|
||||||
if (gcodeIndex % 500 === 0) {
|
|
||||||
// wait 100ms before trying to send again
|
|
||||||
setTimeout(sendGcode, 100);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
drainQueue();
|
|
||||||
} else {
|
|
||||||
console.log("no gcode to send");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setGCode(gc, runbox) {
|
|
||||||
try {
|
|
||||||
gcode = gc.split('\n');
|
|
||||||
bounds = runbox;
|
|
||||||
$('sender-gc-lines').value = gcode ? gcode.length : '';
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function closePort() {
|
|
||||||
if (!selectedPort) return;
|
|
||||||
emit("** closing port: "+selectedPort.Name);
|
|
||||||
socket.send('close '+selectedPort.Name);
|
|
||||||
senderSelectPort.selectedIndex = 0;
|
|
||||||
senderSelectMode.selectedIndex = 0;
|
|
||||||
senderPortClose.disabled = true;
|
|
||||||
selectedPort = null;
|
|
||||||
selectedMode = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updatePortSettings() {
|
|
||||||
// console.log({ups:1, selectedPort:selectedPort, selectedMode:selectedMode});
|
|
||||||
if (selectedPort) {
|
|
||||||
if (selectedPort.IsOpen) {
|
|
||||||
if (selectedMode) {
|
|
||||||
senderPortClose.disabled = false;
|
|
||||||
if (selectedMode != selectedPort.BufferAlgorithm) {
|
|
||||||
alert("to change a port's mode, first close it");
|
|
||||||
selectPort();
|
|
||||||
} else {
|
|
||||||
setTimeout(sendOpenSequence, 500);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
closePort();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (selectedMode) {
|
|
||||||
emit("** opening port: "+selectedPort.Name);
|
|
||||||
socket.send('open '+selectedPort.Name+' 115200 '+selectedMode);
|
|
||||||
senderPortClose.disabled = false;
|
|
||||||
setTimeout(sendOpenSequence, 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI select trigger
|
|
||||||
function selectPort() {
|
|
||||||
var value = senderSelectPort[senderSelectPort.selectedIndex].value,
|
|
||||||
newport = ports[value],
|
|
||||||
algo;
|
|
||||||
if (value >= 0) {
|
|
||||||
selectedPort = newport;
|
|
||||||
// console.log([selectedPort,value]);
|
|
||||||
switch (newport.BufferAlgorithm) {
|
|
||||||
case 'grbl': senderSelectMode.selectedIndex = 1; break;
|
|
||||||
case 'tinyg': senderSelectMode.selectedIndex = 2; break;
|
|
||||||
default: senderSelectMode.selectedIndex = 0; break;
|
|
||||||
}
|
|
||||||
senderPortClose.disabled = !newport.IsOpen;
|
|
||||||
if (newport.BufferAlgorithm) selectMode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI select trigger
|
|
||||||
function selectMode() {
|
|
||||||
if (senderSelectMode.selectedIndex) {
|
|
||||||
selectedMode = senderSelectMode[senderSelectMode.selectedIndex].value;
|
|
||||||
} else {
|
|
||||||
selectedMode = '';
|
|
||||||
}
|
|
||||||
// console.log([senderSelectMode,selectedMode]);
|
|
||||||
updatePortSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updatePortList(portList) {
|
|
||||||
emit("** received port list");
|
|
||||||
|
|
||||||
var portsHTML = '<option>select port</option>',
|
|
||||||
portModes = [];
|
|
||||||
|
|
||||||
ports = portList;
|
|
||||||
ports.forEach(function(port, index) {
|
|
||||||
portsHTML += '<option value='+index+'>' + port.Friendly + '</option>';
|
|
||||||
});
|
|
||||||
|
|
||||||
connect.disabled = false;
|
|
||||||
senderSelectMode.selecteIndex = 0;
|
|
||||||
senderSelectPort.selecteIndex = 0;
|
|
||||||
senderSelectMode.disabled = false;
|
|
||||||
senderSelectPort.disabled = false;
|
|
||||||
senderSelectPort.innerHTML = portsHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
// send immediately bypassing queue
|
|
||||||
function sendNow(cmd) {
|
|
||||||
if (!(socket && selectedPort)) return;
|
|
||||||
socket.send('send '+selectedPort.Name+' '+cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// buffer to mem queue which drains to spjs
|
|
||||||
function sendToQueue(cmd) {
|
|
||||||
localQueue.push(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// spjs ack (wrote) queue entry
|
|
||||||
function queueAck(data) {
|
|
||||||
data.forEach(function(el) {
|
|
||||||
waitingForAck.remove(el.Id);
|
|
||||||
gcLinesSent.value = gcodeIndex - waitingForAck.length;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// drain from mem queue to spjs
|
|
||||||
function drainQueue() {
|
|
||||||
// return if no live socket
|
|
||||||
if (!(socket && selectedPort)) return;
|
|
||||||
|
|
||||||
// return if paused or empty outbound buffer
|
|
||||||
if (gcPaused || localQueue.length === 0) return;
|
|
||||||
|
|
||||||
// return if waiting or queued to queue too large
|
|
||||||
if (waitingForAck.length > 0 || spjsQueueCount > spjsQueueCountMax) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// blast out next batch of queued to queue
|
|
||||||
var toolChange = false,
|
|
||||||
count = 0,
|
|
||||||
data = [],
|
|
||||||
line,
|
|
||||||
next;
|
|
||||||
|
|
||||||
while (count++ < sendBatchMax && localQueue.length > 0) {
|
|
||||||
next = (nextID++).toString();
|
|
||||||
line = localQueue.shift();
|
|
||||||
if (line.indexOf("M6") === 0) {
|
|
||||||
toolChange = true;
|
|
||||||
// grbl doesn't support M6 so
|
|
||||||
// just stop sending until unpaused
|
|
||||||
if (selectedMode === 'grbl') break;
|
|
||||||
}
|
|
||||||
waitingForAck.push(next);
|
|
||||||
data.push({D:line, Id:next});
|
|
||||||
// for tinyg pause after M6 sent
|
|
||||||
if (toolChange) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket.send('sendjson '+o2js({
|
|
||||||
P: selectedPort.Name,
|
|
||||||
Data: data
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (toolChange) {
|
|
||||||
emit("** tool change");
|
|
||||||
setPause(true);
|
|
||||||
var alertToolChange = SDB['sender-alert-toolchange'];
|
|
||||||
if (!alertToolChange && !confirm("tool change. unpause to continue.\nshow this dialog in the future?")) {
|
|
||||||
SDB['sender-alert-toolchange'] = 'no';
|
|
||||||
}
|
|
||||||
// alert("tool change. click unpause to continue");
|
|
||||||
// setPause(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPause(paused) {
|
|
||||||
if (paused === gcPaused) return;
|
|
||||||
gcPaused = paused;
|
|
||||||
senderGcPause.innerHTML = paused ? 'unpause' : 'pause';
|
|
||||||
senderGcPause.style.color = paused ? '#800' : '#000';
|
|
||||||
if (paused) emit("** program paused. unpause to continue");
|
|
||||||
}
|
|
||||||
|
|
||||||
function emit(msg) {
|
|
||||||
if (!logDiv) return console.log({unable_to_emit: msg});
|
|
||||||
if (msg) {
|
|
||||||
msg = msg.replace('<','<').replace('>','>');
|
|
||||||
logBuffer.push(msg);
|
|
||||||
if (logBuffer.length > 100) logBuffer = logBuffer.slice(1);
|
|
||||||
}
|
|
||||||
logDiv.innerHTML = logBuffer.join('<br>');
|
|
||||||
logDiv.scrollTop = logDiv.scrollHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
function jog(axis, delta) {
|
|
||||||
delta = (delta || 1) * (parseFloat(jogInput.value) || 1);
|
|
||||||
sendNow("G91 G0 " + axis + delta.toString());
|
|
||||||
sendNow("G90");
|
|
||||||
}
|
|
||||||
|
|
||||||
function softReset() {
|
|
||||||
sendNow("\x18");
|
|
||||||
// for tinyg, we need to flush the buffer and resume
|
|
||||||
// so that the commands will be processed
|
|
||||||
if (selectedMode === 'tinyg') sendNow('%~');
|
|
||||||
// for grbl, also reset an alarms
|
|
||||||
if (selectedMode === 'grbl') sendNow('$X');
|
|
||||||
}
|
|
||||||
|
|
||||||
function feedHold() {
|
|
||||||
sendNow("!");
|
|
||||||
}
|
|
||||||
|
|
||||||
function feedResume() {
|
|
||||||
sendNow("~");
|
|
||||||
// send unlock if alarm is set
|
|
||||||
if (selectedMode === 'grbl' && status === 'Alarm') sendNow('$X');
|
|
||||||
}
|
|
||||||
|
|
||||||
function runbox() {
|
|
||||||
if (!bounds) return;
|
|
||||||
sendNow(["G0X",bounds.min.x,"Y",bounds.min.y].join(''));
|
|
||||||
sendNow(["G0X",bounds.max.x,"Y",bounds.min.y].join(''));
|
|
||||||
sendNow(["G0X",bounds.max.x,"Y",bounds.max.y].join(''));
|
|
||||||
sendNow(["G0X",bounds.min.x,"Y",bounds.max.y].join(''));
|
|
||||||
sendNow(["G0X0Y0"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function hide() {
|
|
||||||
senderDialog.style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
function show() {
|
|
||||||
senderDialog.style.display = 'block';
|
|
||||||
senderDialog.style.right = (kiri.api.ui.ctrlRight.offsetWidth + 5) + 'px';
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle() {
|
|
||||||
if (senderDialog.style.display === 'block') hide(); else show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function programStart() {
|
|
||||||
gcodeIndex = 0;
|
|
||||||
gcodeAbort = false;
|
|
||||||
gcLinesSent.value = 0;
|
|
||||||
setPause(false);
|
|
||||||
feedResume();
|
|
||||||
sendGcode();
|
|
||||||
}
|
|
||||||
|
|
||||||
function programPause() {
|
|
||||||
setPause(!gcPaused);
|
|
||||||
gcodeAbort = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function programAbort() {
|
|
||||||
gcodeIndex = 0;
|
|
||||||
gcodeAbort = true;
|
|
||||||
gcLinesSent.value = 0;
|
|
||||||
localQueue = [];
|
|
||||||
setPause(false);
|
|
||||||
feedHold();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
30
js/kiri.js
30
js/kiri.js
|
|
@ -880,6 +880,7 @@ self.kiri.license = exports.LICENSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DOC.activeElement.blur();
|
||||||
SPACE.update();
|
SPACE.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1023,10 +1024,6 @@ self.kiri.license = exports.LICENSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
function exportGCode(gcode) {
|
function exportGCode(gcode) {
|
||||||
if (MODE === MODES.CAM) {
|
|
||||||
KIRI.serial.setGCode(gcode, currentPrint.bounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDB['print-seq'] = printSeq++;
|
SDB['print-seq'] = printSeq++;
|
||||||
|
|
||||||
var pre = (MODE === MODES.CAM ? "cnc-" : "print-") + (printSeq.toString().padStart(3,"0")),
|
var pre = (MODE === MODES.CAM ? "cnc-" : "print-") + (printSeq.toString().padStart(3,"0")),
|
||||||
|
|
@ -1262,8 +1259,6 @@ self.kiri.license = exports.LICENSE;
|
||||||
$('print-download').onclick = download;
|
$('print-download').onclick = download;
|
||||||
$('print-octoprint').onclick = sendto_octoprint;
|
$('print-octoprint').onclick = sendto_octoprint;
|
||||||
$('print-gridhost').onclick = sendto_gridhost;
|
$('print-gridhost').onclick = sendto_gridhost;
|
||||||
$('print-serial').onclick = showSerial;
|
|
||||||
$('print-serial').style.display = MODE === MODES.CAM ? '' : 'none';
|
|
||||||
$('print-filament-row').style.display = MODE === MODES.FDM ? '' : 'none';
|
$('print-filament-row').style.display = MODE === MODES.FDM ? '' : 'none';
|
||||||
$('mill-info').style.display = MODE === MODES.CAM ? '' : 'none';
|
$('mill-info').style.display = MODE === MODES.CAM ? '' : 'none';
|
||||||
$('print-filename').value = filename;
|
$('print-filename').value = filename;
|
||||||
|
|
@ -1275,6 +1270,11 @@ self.kiri.license = exports.LICENSE;
|
||||||
calcWeight();
|
calcWeight();
|
||||||
octo_host = $('octo-host');
|
octo_host = $('octo-host');
|
||||||
octo_apik = $('octo-apik');
|
octo_apik = $('octo-apik');
|
||||||
|
if (MODE === MODES.CAM) {
|
||||||
|
$('send-to-octoprint').style.display = 'none';
|
||||||
|
} else {
|
||||||
|
$('send-to-octoprint').style.display = '';
|
||||||
|
}
|
||||||
if (OCTOPRINT) {
|
if (OCTOPRINT) {
|
||||||
$('ophost').style.display = 'none';
|
$('ophost').style.display = 'none';
|
||||||
$('opapik').style.display = 'none';
|
$('opapik').style.display = 'none';
|
||||||
|
|
@ -2110,17 +2110,6 @@ self.kiri.license = exports.LICENSE;
|
||||||
UI.modal.style.display = 'none';
|
UI.modal.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
function showSerial(toggle) {
|
|
||||||
if (MODE !== MODES.CAM) return;
|
|
||||||
hideModal();
|
|
||||||
if (toggle === true) {
|
|
||||||
KIRI.serial.toggle();
|
|
||||||
} else {
|
|
||||||
KIRI.serial.show();
|
|
||||||
}
|
|
||||||
STATS.add('d-sender');
|
|
||||||
}
|
|
||||||
|
|
||||||
function showHelpLocal() {
|
function showHelpLocal() {
|
||||||
showHelp("/kiri/help-kiri.html");
|
showHelp("/kiri/help-kiri.html");
|
||||||
}
|
}
|
||||||
|
|
@ -2183,6 +2172,7 @@ self.kiri.license = exports.LICENSE;
|
||||||
DBUG.log("invalid view mode: "+mode);
|
DBUG.log("invalid view mode: "+mode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
DOC.activeElement.blur();
|
||||||
}
|
}
|
||||||
|
|
||||||
function inMode(mode) {
|
function inMode(mode) {
|
||||||
|
|
@ -2782,9 +2772,6 @@ self.kiri.license = exports.LICENSE;
|
||||||
case cca('C'): // refresh catalog
|
case cca('C'): // refresh catalog
|
||||||
CATALOG.refresh();
|
CATALOG.refresh();
|
||||||
break;
|
break;
|
||||||
case cca('c'): // open control window
|
|
||||||
showSerial(true);
|
|
||||||
break;
|
|
||||||
case cca('i'): // single settings edit
|
case cca('i'): // single settings edit
|
||||||
var v = prompt('edit "'+settings.process.processName+'"', JSON.stringify(settings.process));
|
var v = prompt('edit "'+settings.process.processName+'"', JSON.stringify(settings.process));
|
||||||
if (v) {
|
if (v) {
|
||||||
|
|
@ -3613,9 +3600,6 @@ self.kiri.license = exports.LICENSE;
|
||||||
STATS.add('init');
|
STATS.add('init');
|
||||||
// updateActive(true);
|
// updateActive(true);
|
||||||
|
|
||||||
// init gcode sender
|
|
||||||
KIRI.serial.init();
|
|
||||||
|
|
||||||
// place version number a couple of places to help users
|
// place version number a couple of places to help users
|
||||||
UI.helpButton.title = "version " + KIRI.version;
|
UI.helpButton.title = "version " + KIRI.version;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
var exports = {
|
var exports = {
|
||||||
COPYRIGHT:"Copyright (C) 2014-2019 Stewart Allen <sa@grid.space> - All Rights Reserved",
|
COPYRIGHT:"Copyright (C) 2014-2019 Stewart Allen <sa@grid.space> - All Rights Reserved",
|
||||||
LICENSE:"See the license.md file included with the source distribution",
|
LICENSE:"See the license.md file included with the source distribution",
|
||||||
VERSION:"1.2.9"
|
VERSION:"1.3.0"
|
||||||
};
|
};
|
||||||
if (!module) var module = {};
|
if (!module) var module = {};
|
||||||
module.exports = exports;
|
module.exports = exports;
|
||||||
|
|
|
||||||
|
|
@ -766,8 +766,7 @@ var ver = require('../js/license.js'),
|
||||||
"kiri-print",
|
"kiri-print",
|
||||||
"kiri-codec",
|
"kiri-codec",
|
||||||
"kiri-work",
|
"kiri-work",
|
||||||
"kiri",
|
"kiri"
|
||||||
"kiri-serial"
|
|
||||||
],
|
],
|
||||||
meta : [
|
meta : [
|
||||||
"license",
|
"license",
|
||||||
|
|
|
||||||
5
notes.md
5
notes.md
|
|
@ -5,8 +5,6 @@
|
||||||
* share raw data w/ dups, encode/decode
|
* share raw data w/ dups, encode/decode
|
||||||
* bail on decimation if it's proving ineffective
|
* bail on decimation if it's proving ineffective
|
||||||
* improve decimation speed by avoiding in/out of Point
|
* improve decimation speed by avoiding in/out of Point
|
||||||
* dismissible transient message/alert
|
|
||||||
* modal non-alert-based dialog & spinner
|
|
||||||
* server-side processing (determine protocol and storage)
|
* server-side processing (determine protocol and storage)
|
||||||
* move more kiri code (like printing) into modules like serial
|
* move more kiri code (like printing) into modules like serial
|
||||||
* refactor / simplify POLY.expand (put onus on collector)
|
* refactor / simplify POLY.expand (put onus on collector)
|
||||||
|
|
@ -29,7 +27,8 @@
|
||||||
* feather sharp tips by reducing extrusion in area of overlap
|
* feather sharp tips by reducing extrusion in area of overlap
|
||||||
* dual extruder support
|
* dual extruder support
|
||||||
* add manual supports
|
* add manual supports
|
||||||
* fan / layer control * update forum
|
* fan / layer control
|
||||||
|
* update forum
|
||||||
* option to support interior bridges when 0% infill
|
* option to support interior bridges when 0% infill
|
||||||
* fix multiple part layout export offset (resend position @ print time)
|
* fix multiple part layout export offset (resend position @ print time)
|
||||||
|
|
||||||
|
|
|
||||||
12
package.json
12
package.json
|
|
@ -27,20 +27,20 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"buffer-crc32": "^0.2.13",
|
"buffer-crc32": "^0.2.13",
|
||||||
"compression": "^1.7.3",
|
"compression": "^1.7.4",
|
||||||
"connect": "^3.6.6",
|
"connect": "^3.6.6",
|
||||||
"express-useragent": "^1.0.12",
|
"express-useragent": "^1.0.12",
|
||||||
"level": "^4.0.0",
|
"level": "^4.0.0",
|
||||||
"levelup": "^4.0.0",
|
|
||||||
"leveldown": "^4.0.2",
|
"leveldown": "^4.0.2",
|
||||||
"moment": "^2.22.2",
|
"levelup": "^4.0.0",
|
||||||
|
"moment": "^2.24.0",
|
||||||
"n3d-threejs": "^72.0.0",
|
"n3d-threejs": "^72.0.0",
|
||||||
"three": "^0.96.0",
|
"pixi.js": "^4.8.7",
|
||||||
"pixi.js": "^4.8.2",
|
|
||||||
"request": "^2.88.0",
|
"request": "^2.88.0",
|
||||||
"serve-static": "^1.13.2",
|
"serve-static": "^1.13.2",
|
||||||
|
"three": "^0.96.0",
|
||||||
"tween.js": "^0.14.0",
|
"tween.js": "^0.14.0",
|
||||||
"uglify-es": "^3.3.9",
|
"uglify-es": "^3.3.10",
|
||||||
"validator": "^8.2.0"
|
"validator": "^8.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,103 +33,6 @@
|
||||||
<div id="control-left" class="control"><div id="assets"></div></div>
|
<div id="control-left" class="control"><div id="assets"></div></div>
|
||||||
<!-- right control menu -->
|
<!-- right control menu -->
|
||||||
<div id="control-right" class="control"><div id="control"></div></div>
|
<div id="control-right" class="control"><div id="control"></div></div>
|
||||||
<!-- SPJS gcode sender -->
|
|
||||||
<div id="sender">
|
|
||||||
<div id="sender-bar">
|
|
||||||
<button id="sender-spjs">?</button>
|
|
||||||
<button id="sender-close">X</button>
|
|
||||||
</div>
|
|
||||||
<span>direct device control</span>
|
|
||||||
<div class="sender-sel">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th colspan="2" class="flow-row">
|
|
||||||
<input class="flow-grow" id="sender-host" size="30" spellcheck="false" placeholder="host:port of SPJS server" />
|
|
||||||
</th>
|
|
||||||
<td> <button id="sender-connect">connect</button> </td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th class="flow-row">
|
|
||||||
<select class="flow-grow" id="sender-port" disabled="true"><option>select port</option></select>
|
|
||||||
<select id="sender-mode" disabled="true">
|
|
||||||
<option id="mode-option">set mode</option>
|
|
||||||
<option value="grbl">grbl</option>
|
|
||||||
<option value="tinyg">tinyg</option>
|
|
||||||
</select>
|
|
||||||
</th>
|
|
||||||
<td> <button id="sender-port-close">close</button> </td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="sender-sel"> <div id="sender-log"></div> </div>
|
|
||||||
<div class="sender-sel" id="sender-cc">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<label>status</label>
|
|
||||||
<input id="sender-status" size="5" disabled="true" />
|
|
||||||
<label>send</label>
|
|
||||||
<input id="sender-command" size="30" />
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th class="flow-row" id="sender-quick">
|
|
||||||
<button id="sender-ctrlx">soft reset</button>
|
|
||||||
<button id="sender-hold">feed hold</button>
|
|
||||||
<button id="sender-resume">feed resume</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="sender-sel flow-row flow-space-between" id="sender-pad">
|
|
||||||
<div>
|
|
||||||
<table>
|
|
||||||
<tr><th>
|
|
||||||
<button id="sjx-">X-</button>
|
|
||||||
<button id="sjx+">X+</button>
|
|
||||||
</th></tr>
|
|
||||||
<tr><th>
|
|
||||||
<button id="sjy-">Y-</button>
|
|
||||||
<button id="sjy+">Y+</button>
|
|
||||||
</th></tr>
|
|
||||||
<tr><th>
|
|
||||||
<button id="sjz-">Z-</button>
|
|
||||||
<button id="sjz+">Z+</button>
|
|
||||||
</th></tr>
|
|
||||||
</table>
|
|
||||||
</div><div>
|
|
||||||
<table>
|
|
||||||
<tr><th> <label>jog</label><input id="sender-jog" size="4" value="1" title="jog distance in mm" /><label>mm</label> </th></tr>
|
|
||||||
<tr><th> <button id="sender-set-zero">zero out axes</button> </th></tr>
|
|
||||||
<tr><th> <button id="sender-goto-zero">goto zero axis</button> </th></tr>
|
|
||||||
</table>
|
|
||||||
</div><div>
|
|
||||||
<table id="sender-coordinates">
|
|
||||||
<tr><th><label>X</label> <input id="saxi" disabled="true" size="8" /> <input id="srxi" disabled="true" size="8" /></th></tr>
|
|
||||||
<tr><th><label>Y</label> <input id="sayi" disabled="true" size="8" /> <input id="sryi" disabled="true" size="8" /></th></tr>
|
|
||||||
<tr><th><label>Z</label> <input id="sazi" disabled="true" size="8" /> <input id="srzi" disabled="true" size="8" /></th></tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="sender-sel" id="sender-control">
|
|
||||||
<table>
|
|
||||||
<tr><td>
|
|
||||||
<label>gcode control</label>
|
|
||||||
<div id="sender-control-buttons">
|
|
||||||
<button id="sender-gc-send">send</button>
|
|
||||||
<button id="sender-gc-pause">pause</button>
|
|
||||||
<button id="sender-gc-abort">abort</button>
|
|
||||||
: <button id="sender-gc-runbox">runbox</button>
|
|
||||||
</div>
|
|
||||||
</td></tr>
|
|
||||||
<tr><td class="flow-row flow-space-between">
|
|
||||||
<div><label>queue</label><input id="sender-gc-queue" disabled="true" size="9" /> </div>
|
|
||||||
<div><label>sent</label><input id="sender-gc-sent" disabled="true" size="9" /> </div>
|
|
||||||
<div><label>total</label><input id="sender-gc-lines" disabled="true" size="9" /> </div>
|
|
||||||
</td></tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- all modal dialogs -->
|
<!-- all modal dialogs -->
|
||||||
<div id="modal">
|
<div id="modal">
|
||||||
<div id="help"></div>
|
<div id="help"></div>
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
<div class="print-sel print-gcode flex frow">
|
<div class="print-sel print-gcode flex frow">
|
||||||
<span><label>gcode</label></span>
|
<span><label>gcode</label></span>
|
||||||
<button id="print-download" class="fgro">download</button>
|
<button id="print-download" class="fgro">download</button>
|
||||||
<button id="print-serial" class="fgro">use gcode sender</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="print-sel flex frow" id="send-to-octoprint">
|
<div class="print-sel flex frow" id="send-to-octoprint">
|
||||||
|
|
|
||||||
|
|
@ -235,112 +235,9 @@ select {
|
||||||
background-color: rgba(255,255,255,0.5);
|
background-color: rgba(255,255,255,0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** sender dialog */
|
|
||||||
|
|
||||||
#sender {
|
|
||||||
position: absolute;
|
|
||||||
text-align: center;
|
|
||||||
top: 5px;
|
|
||||||
right: 0px;
|
|
||||||
color: b;acl;
|
|
||||||
border: 3px solid #ddd;
|
|
||||||
border-radius: 3px;
|
|
||||||
background-color: rgba(255,255,255,0.75);
|
|
||||||
padding: 10px;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#sender-bar {
|
|
||||||
border: 0 !important;
|
|
||||||
margin: 2px 2px 0 0 !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 200;
|
|
||||||
right: 3px;
|
|
||||||
top: 3px;
|
|
||||||
}
|
|
||||||
#sender-bar button {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
#sender > div {
|
|
||||||
border: 1px solid #888;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 2px;
|
|
||||||
margin: 6px 0 6px 0;
|
|
||||||
}
|
|
||||||
#sender .sender-sel:hover {
|
|
||||||
border: 1px solid yellow;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
#sender table {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
#sender th {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
#sender td {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
#sender input[disabled] {
|
|
||||||
background-color: #bbb;
|
|
||||||
border-color: #ccc;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
#v a {
|
#v a {
|
||||||
color: #8ae;
|
color: #8ae;
|
||||||
}
|
}
|
||||||
#sender a:hover {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #888;
|
|
||||||
}
|
|
||||||
#sender-log {
|
|
||||||
width: 100%;
|
|
||||||
height: 100px;
|
|
||||||
padding: 5px;
|
|
||||||
overflow: auto;
|
|
||||||
text-align: left;
|
|
||||||
font-size: 11px;
|
|
||||||
max-width: 100em;
|
|
||||||
}
|
|
||||||
#sender-set-zero, #sender-goto-zero, #sender-connect, #sender-port-close {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
#sender-jog {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
#sender label {
|
|
||||||
color: #ddd;
|
|
||||||
background-color: #555;
|
|
||||||
border: 1px solid #aaa;
|
|
||||||
padding-top: 1px;
|
|
||||||
padding-left: 3px;
|
|
||||||
padding-right: 3px;
|
|
||||||
padding-bottom: 1px;
|
|
||||||
}
|
|
||||||
#sender span {
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
#sender-control td {
|
|
||||||
text-align: justify;
|
|
||||||
}
|
|
||||||
#sender-control input {
|
|
||||||
margin-left: 2px;
|
|
||||||
}
|
|
||||||
#sender-control-buttons {
|
|
||||||
float:right;
|
|
||||||
}
|
|
||||||
#sender-status {
|
|
||||||
text-align: center;
|
|
||||||
xbackground-color: #555 !important;
|
|
||||||
xborder: 1px solid black !important;
|
|
||||||
xmargin: 2px 2px 2px 0;
|
|
||||||
xpadding: 2px 2px 2px 0;
|
|
||||||
}
|
|
||||||
#sender-quick button {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
#sender-coordinates input {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** help dialog */
|
/** help dialog */
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue