0
0
mirror of https://github.com/Doodle3D/doodle3d-client.git synced 2024-11-24 18:17:56 +01:00

Merge branch 'develop'

This commit is contained in:
peteruithoven 2014-03-14 15:06:42 +01:00
commit f3577669d2
9 changed files with 676 additions and 560 deletions

View File

@ -62,6 +62,7 @@ define Package/doodle3d-client/install
$(CP) $(PKG_BUILD_DIR)/www/index.html $(1)/www/ $(CP) $(PKG_BUILD_DIR)/www/index.html $(1)/www/
$(CP) $(PKG_BUILD_DIR)/www/settings.html $(1)/www/ $(CP) $(PKG_BUILD_DIR)/www/settings.html $(1)/www/
$(CP) $(PKG_BUILD_DIR)/www/helpcontent.html $(1)/www/ $(CP) $(PKG_BUILD_DIR)/www/helpcontent.html $(1)/www/
$(CP) $(PKG_BUILD_DIR)/www/redirect.html $(1)/www/
$(CP) $(PKG_BUILD_DIR)/www/css/debug.min.css $(1)/www/css/ $(CP) $(PKG_BUILD_DIR)/www/css/debug.min.css $(1)/www/css/
$(CP) $(PKG_BUILD_DIR)/www/css/settings.min.css $(1)/www/css/ $(CP) $(PKG_BUILD_DIR)/www/css/settings.min.css $(1)/www/css/

View File

@ -24,21 +24,21 @@ function Message() {
this.init = function($element) { this.init = function($element) {
this.$element = $element; this.$element = $element;
} }
this.set = function(text,mode,autoHide,disableEffect) { this.set = function(contents,mode,autoHide,disableEffect) {
console.log("Message:set: ",text,mode,autoHide,disableEffect); console.log("Message:set: ",contents,mode,autoHide,disableEffect);
if(disableEffect) { if(disableEffect) {
self.fill(text,mode,autoHide) self.fill(contents,mode,autoHide)
} else{ } else{
self.hide(function() { self.hide(function() {
self.show(); self.show();
self.fill(text,mode,autoHide) self.fill(contents,mode,autoHide)
}); });
} }
} }
this.fill = function(text,mode,autoHide) { this.fill = function(contents,mode,autoHide) {
//console.log("Message:fill: ",text,mode,autoHide); //console.log("Message:fill: ",text,mode,autoHide);
self.clear(); self.clear();
self.$element.text(text); self.$element.html(contents);
self.$element.addClass(mode); self.$element.addClass(mode);
self.mode = mode; self.mode = mode;
clearTimeout(autohideTimeout); clearTimeout(autohideTimeout);
@ -47,7 +47,7 @@ function Message() {
} }
} }
this.clear = function($element) { this.clear = function($element) {
this.$element.text(""); this.$element.html("");
this.$element.removeClass(this.mode); this.$element.removeClass(this.mode);
} }

View File

@ -11,51 +11,52 @@ var $printProgressContainer = $("#printProgressContainer");
var $progressbar = $("#progressbar"); var $progressbar = $("#progressbar");
var $progressAmount = $(".progressAmount"); var $progressAmount = $(".progressAmount");
function setPrintprogress(val) { function setPrintprogress(val) {
if (isNaN(val)) return; if (isNaN(val)) return;
// console.log("f:setPrintprogress() >> val " + val); // console.log("f:setPrintprogress() >> val " + val);
$progressbar.css("width", val*100 + "%"); $progressbar.css("width", val*100 + "%");
$progressAmount.text(Math.floor(val*100) + "%"); $progressAmount.text(Math.floor(val*100) + "%");
} }
//*/ //*/
function Printer() { function Printer() {
Printer.WIFIBOX_DISCONNECTED_STATE = "wifibox disconnected"; Printer.WIFIBOX_DISCONNECTED_STATE = "wifibox disconnected";
Printer.UNKNOWN_STATE = "unknown"; // happens when a printer is connection but there isn't communication yet Printer.UNKNOWN_STATE = "unknown"; // happens when a printer is connection but there isn't communication yet
Printer.DISCONNECTED_STATE = "disconnected"; // printer disconnected Printer.DISCONNECTED_STATE = "disconnected"; // printer disconnected
Printer.IDLE_STATE = "idle"; // printer found, but idle Printer.CONNECTING_STATE = "connecting"; // printer connecting (printer found, but driver has not yet finished setting up the connection)
Printer.BUFFERING_STATE = "buffering"; // printer is buffering (recieving) data, but not yet printing Printer.IDLE_STATE = "idle"; // printer found and ready to use, but idle
Printer.PRINTING_STATE = "printing"; Printer.BUFFERING_STATE = "buffering"; // printer is buffering (recieving) data, but not yet printing
Printer.STOPPING_STATE = "stopping"; // when you stop (abort) a print it prints the endcode Printer.PRINTING_STATE = "printing";
Printer.TOUR_STATE = "tour"; // when in joyride mode Printer.STOPPING_STATE = "stopping"; // when you stop (abort) a print it prints the endcode
Printer.TOUR_STATE = "tour"; // when in joyride mode
Printer.ON_BEFORE_UNLOAD_MESSAGE = "You're doodle is still being send to the printer, leaving will result in a incomplete 3D print"; Printer.ON_BEFORE_UNLOAD_MESSAGE = "You're doodle is still being sent to the printer, leaving will result in a incomplete 3D print";
this.temperature = 0; this.temperature = 0;
this.targetTemperature = 0; this.targetTemperature = 0;
this.currentLine = 0; this.currentLine = 0;
this.totalLines = 0; this.totalLines = 0;
this.bufferedLines = 0; this.bufferedLines = 0;
this.state = Printer.UNKNOWN_STATE; this.state = Printer.UNKNOWN_STATE;
this.hasControl = true; // whether this client has control access this.hasControl = true; // whether this client has control access
this.wifiboxURL; this.wifiboxURL;
this.checkStatusInterval = 3000; this.checkStatusInterval = 3000;
this.checkStatusDelay; this.checkStatusDelay;
this.timeoutTime = 3000; this.timeoutTime = 3000;
this.sendPrintPartTimeoutTime = 5000; this.sendPrintPartTimeoutTime = 5000;
this.gcode; // gcode to be printed this.gcode; // gcode to be printed
this.sendLength = 500; // max amount of gcode lines per post (limited because WiFi box can't handle to much) this.sendLength = 500; // max amount of gcode lines per post (limited because WiFi box can't handle too much)
this.retryDelay = 2000; // retry setTimout delay this.retryDelay = 2000; // retry setTimout delay
this.retrySendPrintPartDelay; // retry setTimout instance this.retrySendPrintPartDelay; // retry setTimout instance
this.retryCheckStatusDelay; // retry setTimout instance this.retryCheckStatusDelay; // retry setTimout instance
this.retryStopDelay; // retry setTimout instance this.retryStopDelay; // retry setTimout instance
this.retryPreheatDelay; // retry setTimout instance this.retryPreheatDelay; // retry setTimout instance
Printer.MAX_GCODE_SIZE = 10; // max size of gcode in MB's (estimation) Printer.MAX_GCODE_SIZE = 10; // max size of gcode in MB's (estimation)
this.stateOverruled = false; this.stateOverruled = false;
@ -65,40 +66,36 @@ function Printer() {
var self = this; var self = this;
this.init = function() { this.init = function() {
//console.log("Printer:init"); //console.log("Printer:init");
//this.wifiboxURL = "http://" + window.location.host + "/cgi-bin/d3dapi"; //this.wifiboxURL = "http://" + window.location.host + "/cgi-bin/d3dapi";
//this.wifiboxURL = "http://192.168.5.1/cgi-bin/d3dapi"; //this.wifiboxURL = "http://192.168.5.1/cgi-bin/d3dapi";
this.wifiboxURL = wifiboxURL; this.wifiboxURL = wifiboxURL;
//this.wifiboxURL = "proxy5.php"; //this.wifiboxURL = "proxy5.php";
//console.log(" wifiboxURL: ",this.wifiboxURL); //console.log(" wifiboxURL: ",this.wifiboxURL);
if(autoUpdate) { if (autoUpdate) {
this.startStatusCheckInterval(); this.startStatusCheckInterval();
} }
} }
this.preheat = function() { this.preheat = function() {
console.log("Printer:preheat"); console.log("Printer:preheat");
if( this.state == Printer.BUFFERING_STATE || if (this.state != Printer.IDLE_STATE) return;
this.state == Printer.PRINTING_STATE ||
this.state == Printer.STOPPING_STATE) {
return;
}
var self = this; var self = this;
if (communicateWithWifibox) { if (communicateWithWifibox) {
$.ajax({ $.ajax({
url: this.wifiboxURL + "/printer/heatup", url: this.wifiboxURL + "/printer/heatup",
type: "POST", type: "POST",
dataType: 'json', dataType: 'json',
timeout: this.timeoutTime, timeout: this.timeoutTime,
success: function(data){ success: function(data){
console.log("Printer:preheat response: ",data); console.log("Printer:preheat response: ",data);
if(data.status != "success") { if(data.status != "success") {
clearTimeout(self.retryPreheatDelay); clearTimeout(self.retryPreheatDelay);
self.retryPreheatDelay = setTimeout(function() { self.preheat() },self.retryDelay); // retry after delay self.retryPreheatDelay = setTimeout(function() { self.preheat() },self.retryDelay); // retry after delay
} }
} }
}).fail(function() { }).fail(function() {
console.log("Printer:preheat: failed"); console.log("Printer:preheat: failed");
@ -106,49 +103,52 @@ function Printer() {
self.retryPreheatDelay = setTimeout(function() { self.preheat() },self.retryDelay); // retry after delay self.retryPreheatDelay = setTimeout(function() { self.preheat() },self.retryDelay); // retry after delay
}); });
} else { } else {
console.log ("Printer >> f:preheat() >> communicateWithWifibox is false, so not executing this function"); console.log ("Printer >> f:preheat() >> communicateWithWifibox is false, so not executing this function");
} }
} }
this.print = function(gcode) { this.print = function(gcode) {
console.log("Printer:print"); console.log("Printer:print");
console.log(" gcode total # of lines: " + gcode.length); console.log(" gcode total # of lines: " + gcode.length);
message.set("Sending doodle to printer...",Message.NOTICE); message.set("Sending doodle to printer...",Message.NOTICE);
self.addLeaveWarning(); self.addLeaveWarning();
/*for (i = 0; i < gcode.length; i++) { /*for (i = 0; i < gcode.length; i++) {
gcode[i] += " (" + i + ")"; gcode[i] += " (" + i + ")";
}*/ }*/
this.sendIndex = 0; this.sendIndex = 0;
this.gcode = gcode; this.gcode = gcode;
//console.log(" gcode[20]: ",gcode[20]); //console.log(" gcode[20]: ",gcode[20]);
var gcodeLineSize = this.byteSize(gcode[20]); var gcodeLineSize = this.byteSize(gcode[20]);
//console.log(" gcodeLineSize: ",gcodeLineSize); //console.log(" gcodeLineSize: ",gcodeLineSize);
var gcodeSize = gcodeLineSize*gcode.length/1024/1024; // estimate gcode size in MB's var gcodeSize = gcodeLineSize*gcode.length/1024/1024; // estimate gcode size in MB's
console.log(" gcodeSize: ",gcodeSize); console.log(" gcodeSize: ",gcodeSize);
if(gcodeSize > Printer.MAX_GCODE_SIZE) { if(gcodeSize > Printer.MAX_GCODE_SIZE) {
alert("Error: Printer:print: gcode file is probably too big ("+gcodeSize+"MB) (max: "+Printer.MAX_GCODE_SIZE+"MB)"); var msg = "Error: Printer:print: gcode file is probably too big ("+gcodeSize+"MB) (max: "+Printer.MAX_GCODE_SIZE+"MB)";
console.log("Error: Printer:print: gcode file is probably too big ("+gcodeSize+"MB) (max: "+Printer.MAX_GCODE_SIZE+"MB)"); alert(msg);
console.log(msg);
this.overruleState(Printer.IDLE_STATE); this.overruleState(Printer.IDLE_STATE);
this.startStatusCheckInterval(); this.startStatusCheckInterval();
message.hide(); message.hide();
self.removeLeaveWarning(); self.removeLeaveWarning();
return; return;
} }
//this.targetTemperature = settings["printer.temperature"]; // slight hack //this.targetTemperature = settings["printer.temperature"]; // slight hack
this.sendPrintPart(this.sendIndex, this.sendLength); this.sendPrintPart(this.sendIndex, this.sendLength);
} }
this.byteSize = function(s){ this.byteSize = function(s){
return~-encodeURI(s).split(/%..|./).length; return~-encodeURI(s).split(/%..|./).length;
} }
this.sendPrintPart = function(sendIndex,sendLength) { this.sendPrintPart = function(sendIndex,sendLength) {
console.log("Printer:sendPrintPart sendIndex: " + sendIndex + "/" + this.gcode.length + ", sendLength: " + sendLength); console.log("Printer:sendPrintPart sendIndex: " + sendIndex + "/" + this.gcode.length + ", sendLength: " + sendLength);
@ -156,49 +156,49 @@ function Printer() {
var sendPercentage = Math.round(sendIndex/this.gcode.length*100); var sendPercentage = Math.round(sendIndex/this.gcode.length*100);
message.set("Sending doodle to printer: "+sendPercentage+"%",Message.NOTICE,false,true); message.set("Sending doodle to printer: "+sendPercentage+"%",Message.NOTICE,false,true);
var firstOne = (sendIndex == 0)? true : false; var firstOne = (sendIndex == 0)? true : false;
var start = firstOne; // start printing right away var start = firstOne; // start printing right away
var completed = false; var completed = false;
if (this.gcode.length < (sendIndex + sendLength)) { if (this.gcode.length < (sendIndex + sendLength)) {
console.log(" sending less than max sendLength (and last)"); console.log(" sending less than max sendLength (and last)");
sendLength = this.gcode.length - sendIndex; sendLength = this.gcode.length - sendIndex;
//lastOne = true; //lastOne = true;
completed = true; completed = true;
} }
var gcodePart = this.gcode.slice(sendIndex, sendIndex+sendLength); var gcodePart = this.gcode.slice(sendIndex, sendIndex+sendLength);
var postData = { gcode: gcodePart.join("\n"), first: firstOne, start: start}; var postData = { gcode: gcodePart.join("\n"), first: firstOne, start: start};
var self = this; var self = this;
if (communicateWithWifibox) { if (communicateWithWifibox) {
$.ajax({ $.ajax({
url: this.wifiboxURL + "/printer/print", url: this.wifiboxURL + "/printer/print",
type: "POST", type: "POST",
data: postData, data: postData,
dataType: 'json', dataType: 'json',
timeout: this.sendPrintPartTimeoutTime, timeout: this.sendPrintPartTimeoutTime,
success: function(data){ success: function(data){
console.log("Printer:sendPrintPart response: ",data); console.log("Printer:sendPrintPart response: ",data);
if(data.status == "success") { if(data.status == "success") {
if (completed) { if (completed) {
console.log("Printer:sendPrintPart:gcode sending completed"); console.log("Printer:sendPrintPart:gcode sending completed");
this.gcode = []; this.gcode = [];
btnStop.css("display","block"); // hack btnStop.css("display","block"); // hack
self.removeLeaveWarning(); self.removeLeaveWarning();
message.set("Doodle has been sent to printer...",Message.INFO,true); message.set("Doodle has been sent to printer...",Message.INFO,true);
//self.targetTemperature = settings["printer.temperature"]; // slight hack //self.targetTemperature = settings["printer.temperature"]; // slight hack
} else { } else {
// only if the state hasn't bin changed (by for example pressing stop) we send more gcode // only if the state hasn't been changed (by for example pressing stop) we send more gcode
//console.log("Printer:sendPrintPart:gcode part received (state: ",self.state,")"); //console.log("Printer:sendPrintPart:gcode part received (state: ",self.state,")");
if(self.state == Printer.PRINTING_STATE || self.state == Printer.BUFFERING_STATE) { if(self.state == Printer.PRINTING_STATE || self.state == Printer.BUFFERING_STATE) {
//console.log("Printer:sendPrintPart:sending next part"); //console.log("Printer:sendPrintPart:sending next part");
self.sendPrintPart(sendIndex + sendLength, sendLength); self.sendPrintPart(sendIndex + sendLength, sendLength);
} }
} }
} }
// after we know the first gcode packed has bin received or failed // after we know the first gcode packed has bin received or failed
// (and the driver had time to update the printer.state) // (and the driver had time to update the printer.state)
// we start checking the status again // we start checking the status again
if(sendIndex == 0) { if(sendIndex == 0) {
@ -219,31 +219,31 @@ function Printer() {
self.startStatusCheckInterval(); self.startStatusCheckInterval();
}); });
} else { } else {
console.log ("Printer >> f:sendPrintPart() >> communicateWithWifibox is false, so not executing this function"); console.log ("Printer >> f:sendPrintPart() >> communicateWithWifibox is false, so not executing this function");
} }
} }
this.stop = function() { this.stop = function() {
console.log("Printer:stop"); console.log("Printer:stop");
endCode = generateEndCode(); endCode = generateEndCode();
console.log(" endCode: ",endCode); console.log(" endCode: ",endCode);
var postData = { gcode: endCode.join("\n")}; var postData = { gcode: endCode.join("\n")};
var self = this; var self = this;
if (communicateWithWifibox) { if (communicateWithWifibox) {
$.ajax({ $.ajax({
url: this.wifiboxURL + "/printer/stop", url: this.wifiboxURL + "/printer/stop",
type: "POST", type: "POST",
data: postData, data: postData,
dataType: 'json', dataType: 'json',
timeout: this.timeoutTime, timeout: this.timeoutTime,
success: function(data){ success: function(data){
console.log("Printer:stop response: ", data); console.log("Printer:stop response: ", data);
// after we know the stop has bin received or failed // after we know the stop has bin received or failed
// (and the driver had time to update the printer.state) // (and the driver had time to update the printer.state)
// we start checking the status again // we start checking the status again
self.startStatusCheckInterval(); self.startStatusCheckInterval();
} }
}).fail(function() { }).fail(function() {
console.log("Printer:stop: failed"); console.log("Printer:stop: failed");
clearTimeout(self.retryStopDelay); clearTimeout(self.retryStopDelay);
@ -255,9 +255,10 @@ function Printer() {
self.startStatusCheckInterval(); self.startStatusCheckInterval();
}); });
} else { } else {
console.log ("Printer >> f:communicateWithWifibox() >> communicateWithWifibox is false, so not executing this function"); console.log ("Printer >> f:stop() >> communicateWithWifibox is false, so not executing this function");
} }
} }
this.startStatusCheckInterval = function() { this.startStatusCheckInterval = function() {
console.log("Printer:startStatusCheckInterval"); console.log("Printer:startStatusCheckInterval");
self.checkStatus(); self.checkStatus();
@ -265,42 +266,45 @@ function Printer() {
clearTimeout(self.retryCheckStatusDelay); clearTimeout(self.retryCheckStatusDelay);
self.checkStatusDelay = setTimeout(function() { self.checkStatus() }, self.checkStatusInterval); self.checkStatusDelay = setTimeout(function() { self.checkStatus() }, self.checkStatusInterval);
} }
this.stopStatusCheckInterval = function() { this.stopStatusCheckInterval = function() {
console.log("Printer:stopStatusCheckInterval"); console.log("Printer:stopStatusCheckInterval");
clearTimeout(self.checkStatusDelay); clearTimeout(self.checkStatusDelay);
clearTimeout(self.retryCheckStatusDelay); clearTimeout(self.retryCheckStatusDelay);
} }
this.checkStatus = function() { this.checkStatus = function() {
//console.log("Printer:checkStatus"); //console.log("Printer:checkStatus");
this.stateOverruled = false; this.stateOverruled = false;
//console.log(" stateOverruled: ",this.stateOverruled); //console.log(" stateOverruled: ",this.stateOverruled);
var self = this; var self = this;
if (communicateWithWifibox) { if (communicateWithWifibox) {
$.ajax({ $.ajax({
url: this.wifiboxURL + "/info/status", url: this.wifiboxURL + "/info/status",
dataType: 'json', dataType: 'json',
timeout: this.timeoutTime, timeout: this.timeoutTime,
success: function(response){ success: function(response){
//console.log(" Printer:status: ",response.data.state); //," response: ",response); //console.log(" Printer:status: ",response.data.state); //," response: ",response);
self.handleStatusUpdate(response); self.handleStatusUpdate(response);
clearTimeout(self.checkStatusDelay); clearTimeout(self.checkStatusDelay);
clearTimeout(self.retryCheckStatusDelay); clearTimeout(self.retryCheckStatusDelay);
self.checkStatusDelay = setTimeout(function() { self.checkStatus() }, self.checkStatusInterval); self.checkStatusDelay = setTimeout(function() { self.checkStatus() }, self.checkStatusInterval);
} }
}).fail(function() { }).fail(function() {
console.log("Printer:checkStatus: failed"); console.log("Printer:checkStatus: failed");
self.state = Printer.WIFIBOX_DISCONNECTED_STATE; self.state = Printer.WIFIBOX_DISCONNECTED_STATE;
clearTimeout(self.checkStatusDelay); clearTimeout(self.checkStatusDelay);
clearTimeout(self.retryCheckStatusDelay); clearTimeout(self.retryCheckStatusDelay);
self.retryCheckStatusDelay = setTimeout(function() { self.checkStatus() },self.retryDelay); // retry after delay self.retryCheckStatusDelay = setTimeout(function() { self.checkStatus() },self.retryDelay); // retry after delay
$(document).trigger(Printer.UPDATE); $(document).trigger(Printer.UPDATE);
}); });
} else { } else {
console.log ("Printer >> f:checkStatus() >> communicateWithWifibox is false, so not executing this function"); console.log ("Printer >> f:checkStatus() >> communicateWithWifibox is false, so not executing this function");
} }
} }
this.handleStatusUpdate = function(response) { this.handleStatusUpdate = function(response) {
//console.log("Printer:handleStatusUpdate response: ",response); //console.log("Printer:handleStatusUpdate response: ",response);
var data = response.data; var data = response.data;
@ -310,21 +314,21 @@ function Printer() {
// state // state
//console.log(" stateOverruled: ",this.stateOverruled); //console.log(" stateOverruled: ",this.stateOverruled);
if(!this.stateOverruled) { if(!this.stateOverruled) {
self.state = data.state; self.state = data.state;
//console.log(" state > ",self.state); //console.log(" state > ",self.state);
} }
// temperature // temperature
self.temperature = data.hotend; self.temperature = data.hotend;
self.targetTemperature = data.hotend_target; self.targetTemperature = data.hotend_target;
// progress // progress
self.currentLine = data.current_line; self.currentLine = data.current_line;
self.totalLines = data.total_lines; self.totalLines = data.total_lines;
self.bufferedLines = data.buffered_lines self.bufferedLines = data.buffered_lines
// access // access
self.hasControl = data.has_control; self.hasControl = data.has_control;
if(self.state == Printer.PRINTING_STATE || self.state == Printer.STOPPING_STATE) { if(self.state == Printer.PRINTING_STATE || self.state == Printer.STOPPING_STATE) {
console.log("progress: ",self.currentLine+"/"+self.totalLines+" ("+self.bufferedLines+") ("+self.state+")"); console.log("progress: ",self.currentLine+"/"+self.totalLines+" ("+self.bufferedLines+") ("+self.state+")");
@ -332,6 +336,7 @@ function Printer() {
} }
$(document).trigger(Printer.UPDATE); $(document).trigger(Printer.UPDATE);
} }
this.overruleState = function(newState) { this.overruleState = function(newState) {
this.stateOverruled = true; this.stateOverruled = true;
console.log(" stateOverruled: ",this.stateOverruled); console.log(" stateOverruled: ",this.stateOverruled);
@ -346,10 +351,11 @@ function Printer() {
this.removeLeaveWarning = function() { this.removeLeaveWarning = function() {
window.onbeforeunload = null; window.onbeforeunload = null;
} }
this.addLeaveWarning = function() { this.addLeaveWarning = function() {
window.onbeforeunload = function() { window.onbeforeunload = function() {
console.log("WARNING:"+Printer.ON_BEFORE_UNLOAD_MESSAGE); console.log("WARNING:"+Printer.ON_BEFORE_UNLOAD_MESSAGE);
return Printer.ON_BEFORE_UNLOAD_MESSAGE; return Printer.ON_BEFORE_UNLOAD_MESSAGE;
}; };
} }
} }

View File

@ -21,113 +21,117 @@ var hasControl;
var gcodeGenerateDelayer; var gcodeGenerateDelayer;
var gcodeGenerateDelay = 50; var gcodeGenerateDelay = 50;
var preheatDelay; var preheatDelay;
var preheatDelayTime = 15*1000; var preheatDelayTime = 15*1000;
function initButtonBehavior() { var connectingHintDelay = null;
console.log("f:initButtonBehavior"); var connectingHintDelayTime = 20 * 1000;
btnOops = new Button("#btnOops");
btnInfo = new Button("#btnInfo"); function initButtonBehavior() {
btnSettings = new Button("#btnSettings"); console.log("f:initButtonBehavior");
btnNew = new Button("#btnNew");
btnPrint= new Button("#btnPrint"); btnOops = new Button("#btnOops");
btnStop = new Button("#btnStop"); btnInfo = new Button("#btnInfo");
btnPrevious = new Button("#btnPrevious"); btnSettings = new Button("#btnSettings");
btnNext = new Button("#btnNext"); btnNew = new Button("#btnNew");
btnSave = new Button("#btnSave"); btnPrint= new Button("#btnPrint");
buttonGroupAdd = $("#buttonGroupAdd"); btnStop = new Button("#btnStop");
btnPrevious = new Button("#btnPrevious");
btnNext = new Button("#btnNext");
btnSave = new Button("#btnSave");
buttonGroupAdd = $("#buttonGroupAdd");
btnShape = new Button("#btnShape"); btnShape = new Button("#btnShape");
btnWordArt = new Button("#btnWordArt"); btnWordArt = new Button("#btnWordArt");
popupWordArt = $("#popupWordArt"); popupWordArt = $("#popupWordArt");
popupShape = $("#popupShape"); popupShape = $("#popupShape");
popupMask = $("#popupMask"); popupMask = $("#popupMask");
logoPanel = $("#logopanel"); logoPanel = $("#logopanel");
btnToggleEdit = new Button("#btnToggleEdit"); btnToggleEdit = new Button("#btnToggleEdit");
buttonGroupEdit = $("#buttonGroupEdit"); buttonGroupEdit = $("#buttonGroupEdit");
btnZoom = new Button("#btnZoom"); btnZoom = new Button("#btnZoom");
btnMove = new Button("#btnMove"); btnMove = new Button("#btnMove");
btnRotate = new Button("#btnRotate"); btnRotate = new Button("#btnRotate");
btnToggleVerticalShapes = new Button("#btnToggleVerticalShapes"); btnToggleVerticalShapes = new Button("#btnToggleVerticalShapes");
buttonGroupVerticalShapes = $("#buttonGroupVerticalShapes"); buttonGroupVerticalShapes = $("#buttonGroupVerticalShapes");
btnHeight = new Button("#btnHeight"); btnHeight = new Button("#btnHeight");
btnTwist = new Button("#btnTwist"); btnTwist = new Button("#btnTwist");
btnStraight = new Button("#btnStraight"); btnStraight = new Button("#btnStraight");
btnDiv = new Button("#btnDiv"); btnDiv = new Button("#btnDiv");
btnConv = new Button("#btnConv"); btnConv = new Button("#btnConv");
btnSine = new Button("#btnSine"); btnSine = new Button("#btnSine");
btnAdd = new Button("#btnAdd"); btnAdd = new Button("#btnAdd");
$(".btn").Button(); //initalize other buttons $(".btn").Button(); //initalize other buttons
logoPanel.on("onButtonClick", onLogo); logoPanel.on("onButtonClick", onLogo);
btnNew.on("onButtonClick", onBtnNew); btnNew.on("onButtonClick", onBtnNew);
btnAdd.on("onButtonClick", onBtnAdd); btnAdd.on("onButtonClick", onBtnAdd);
btnWordArt.on("onButtonClick", onBtnWordArt); btnWordArt.on("onButtonClick", onBtnWordArt);
btnShape.on("onButtonClick", onBtnShape); btnShape.on("onButtonClick", onBtnShape);
btnPrint.on("onButtonClick", print); btnPrint.on("onButtonClick", print);
btnStop.on("onButtonClick", stopPrint); btnStop.on("onButtonClick", stopPrint);
btnSave.on("onButtonClick", saveSketch); btnSave.on("onButtonClick", saveSketch);
btnPrevious.on("onButtonClick", prevDoodle); btnPrevious.on("onButtonClick", prevDoodle);
btnNext.on("onButtonClick", nextDoodle); btnNext.on("onButtonClick", nextDoodle);
btnOops.on("onButtonHold", onBtnOops); btnOops.on("onButtonHold", onBtnOops);
// vertical shape buttons // vertical shape buttons
btnToggleVerticalShapes.on("onButtonClick", onBtnToggleVerticalShapes); btnToggleVerticalShapes.on("onButtonClick", onBtnToggleVerticalShapes);
btnHeight.on("onButtonHold", onBtnHeight); btnHeight.on("onButtonHold", onBtnHeight);
btnTwist.on("onButtonHold", onBtnTwist); btnTwist.on("onButtonHold", onBtnTwist);
btnStraight.on("onButtonClick", onBtnStraight); btnStraight.on("onButtonClick", onBtnStraight);
btnDiv.on("onButtonClick", onBtnDiv); btnDiv.on("onButtonClick", onBtnDiv);
btnConv.on("onButtonClick", onBtnConv); btnConv.on("onButtonClick", onBtnConv);
btnSine.on("onButtonClick", onBtnSine); btnSine.on("onButtonClick", onBtnSine);
btnToggleEdit.on("onButtonClick", onBtnToggleEdit); btnToggleEdit.on("onButtonClick", onBtnToggleEdit);
btnMove.on("onButtonHold", onBtnMove); btnMove.on("onButtonHold", onBtnMove);
btnZoom.on("onButtonHold", onBtnZoom); btnZoom.on("onButtonHold", onBtnZoom);
btnRotate.on("onButtonHold", onBtnRotate); btnRotate.on("onButtonHold", onBtnRotate);
getSavedSketchStatus(); getSavedSketchStatus();
setSketchModified(false); setSketchModified(false);
function onBtnToggleVerticalShapes() { function onBtnToggleVerticalShapes() {
var btnImg; var btnImg;
if(buttonGroupVerticalShapes.is(":hidden")) { if (buttonGroupVerticalShapes.is(":hidden")) {
btnImg = "img/buttons/btnArrowClose.png"; btnImg = "img/buttons/btnArrowClose.png";
} else { } else {
btnImg = "img/buttons/btnArrowOpen.png"; btnImg = "img/buttons/btnArrowOpen.png";
} }
btnToggleVerticalShapes.attr("src",btnImg); btnToggleVerticalShapes.attr("src",btnImg);
buttonGroupVerticalShapes.fadeToggle(BUTTON_GROUP_SHOW_DURATION); buttonGroupVerticalShapes.fadeToggle(BUTTON_GROUP_SHOW_DURATION);
}
function onLogo() {
location.reload();
} }
function onBtnAdd() {
buttonGroupAdd.fadeToggle(BUTTON_GROUP_SHOW_DURATION);
}
function onBtnStraight() { function onLogo() {
setVerticalShape(verticalShapes.NONE); location.reload();
} }
function onBtnDiv() {
setVerticalShape(verticalShapes.DIVERGING);
}
function onBtnConv() {
setVerticalShape(verticalShapes.CONVERGING);
}
function onBtnSine() {
setVerticalShape(verticalShapes.SINUS);
}
function hitTest(cursor,button,radius) { function onBtnAdd() {
return distance(cursor.x,cursor.y,button.x,button.y)<radius; buttonGroupAdd.fadeToggle(BUTTON_GROUP_SHOW_DURATION);
} }
function onBtnStraight() {
setVerticalShape(verticalShapes.NONE);
}
function onBtnDiv() {
setVerticalShape(verticalShapes.DIVERGING);
}
function onBtnConv() {
setVerticalShape(verticalShapes.CONVERGING);
}
function onBtnSine() {
setVerticalShape(verticalShapes.SINUS);
}
function hitTest(cursor,button,radius) {
return distance(cursor.x,cursor.y,button.x,button.y)<radius;
}
function onBtnToggleEdit() { function onBtnToggleEdit() {
var btnImg; var btnImg;
if(buttonGroupEdit.is(":hidden")) { if(buttonGroupEdit.is(":hidden")) {
btnImg = "img/buttons/btnArrowClose.png"; btnImg = "img/buttons/btnArrowClose.png";
} else { } else {
@ -136,7 +140,7 @@ function initButtonBehavior() {
btnToggleEdit.attr("src",btnImg); btnToggleEdit.attr("src",btnImg);
buttonGroupEdit.fadeToggle(BUTTON_GROUP_SHOW_DURATION); buttonGroupEdit.fadeToggle(BUTTON_GROUP_SHOW_DURATION);
} }
function onBtnMove(e,cursor) { function onBtnMove(e,cursor) {
var w = btnMove.width(); var w = btnMove.width();
var h = btnMove.height(); var h = btnMove.height();
@ -156,83 +160,82 @@ function initButtonBehavior() {
rotateShape(-multiplier); rotateShape(-multiplier);
} }
function onBtnHeight(e,cursor) { function onBtnHeight(e,cursor) {
var h = btnHeight.height(); var h = btnHeight.height();
if(cursor.y < h/2) { if(cursor.y < h/2) {
previewUp(true); previewUp(true);
} else { } else {
previewDown(true); previewDown(true);
} }
} }
function onBtnTwist(e,cursor) { function onBtnTwist(e,cursor) {
var h = btnTwist.height(); var h = btnTwist.height();
var multiplier = (cursor.y-h/2)*0.0005; var multiplier = (cursor.y-h/2)*0.0005;
previewTwist(multiplier,true); previewTwist(multiplier,true);
} }
function onBtnOops(e) { function onBtnOops(e) {
oopsUndo(); oopsUndo();
} }
function onBtnNew(e) { function onBtnNew(e) {
clearDoodle(); clearDoodle();
} }
function onBtnWordArt(e) { function onBtnWordArt(e) {
showWordArtDialog(); showWordArtDialog();
} }
function onBtnShape(e) { function onBtnShape(e) {
showShapeDialog(); showShapeDialog();
buttonGroupAdd.fadeOut(); buttonGroupAdd.fadeOut();
} }
btnSettings.on("onButtonClick", openSettingsWindow); btnSettings.on("onButtonClick", openSettingsWindow);
// 29-okt-2013 - we're not doing help for smartphones at the moment // 29-okt-2013 - we're not doing help for smartphones at the moment
if (clientInfo.isSmartphone) { if (clientInfo.isSmartphone) {
btnInfo.disable(); btnInfo.disable();
} else { } else {
btnInfo.on("onButtonClick", function(e) { btnInfo.on("onButtonClick", function(e) {
helpTours.startTour(helpTours.WELCOMETOUR); helpTours.startTour(helpTours.WELCOMETOUR);
}); });
} }
} }
function stopPrint() { function stopPrint() {
console.log("f:stopPrint() >> sendPrintCommands = " + sendPrintCommands); console.log("f:stopPrint() >> sendPrintCommands = " + sendPrintCommands);
//if (!confirm("Weet je zeker dat je huidige print wilt stoppen?")) return; if (sendPrintCommands) printer.stop();
if (sendPrintCommands) printer.stop(); //setState(Printer.STOPPING_STATE,printer.hasControl);
//setState(Printer.STOPPING_STATE,printer.hasControl); printer.overruleState(Printer.STOPPING_STATE);
printer.overruleState(Printer.STOPPING_STATE);
} }
function print(e) { function print(e) {
console.log("f:print() >> sendPrintCommands = " + sendPrintCommands); console.log("f:print() >> sendPrintCommands = " + sendPrintCommands);
//$(".btnPrint").css("display","none"); //$(".btnPrint").css("display","none");
if (_points.length > 2) { if (_points.length > 2) {
//setState(Printer.BUFFERING_STATE,printer.hasControl); //setState(Printer.BUFFERING_STATE,printer.hasControl);
printer.overruleState(Printer.BUFFERING_STATE); printer.overruleState(Printer.BUFFERING_STATE);
btnStop.css("display","none"); // hack btnStop.css("display","none"); // hack
// we put the gcode generation in a little delay // we put the gcode generation in a little delay
// so that for example the print button is disabled right away // so that for example the print button is disabled right away
clearTimeout(gcodeGenerateDelayer); clearTimeout(gcodeGenerateDelayer);
gcodeGenerateDelayer = setTimeout(function() { gcodeGenerateDelayer = setTimeout(function() {
var gcode = generate_gcode(); var gcode = generate_gcode();
if (sendPrintCommands) { if (sendPrintCommands) {
if(gcode.length > 0) { if(gcode.length > 0) {
printer.print(gcode); printer.print(gcode);
} else { } else {
printer.overruleState(Printer.IDLE_STATE); printer.overruleState(Printer.IDLE_STATE);
printer.startStatusCheckInterval(); printer.startStatusCheckInterval();
} }
} else { } else {
console.log("sendPrintCommands is false: not sending print command to 3dprinter"); console.log("sendPrintCommands is false: not sending print command to 3dprinter");
} }
@ -242,75 +245,71 @@ function print(e) {
// $("#textdump").text(gcode.join("\n")); // $("#textdump").text(gcode.join("\n"));
// } // }
}, gcodeGenerateDelay); }, gcodeGenerateDelay);
} else { } else {
console.log("f:print >> not enough points!"); console.log("f:print >> not enough points!");
} }
//alert("Je tekening zal nu geprint worden"); // $.post("/doodle3d.of", { data:output }, function(data) {
//$(".btnPrint").css("display","block"); // btnPrint.disabled = false;
// });
// $.post("/doodle3d.of", { data:output }, function(data) {
// btnPrint.disabled = false;
// });
} }
function clearMainView() { function clearMainView() {
// console.log("f:clearMainView()"); // console.log("f:clearMainView()");
ctx.save(); ctx.save();
ctx.clearRect(0,0,canvas.width, canvas.height); ctx.clearRect(0,0,canvas.width, canvas.height);
ctx.restore(); ctx.restore();
} }
function resetPreview() { function resetPreview() {
// console.log("f:resetPreview()"); // console.log("f:resetPreview()");
// clear preview canvas // clear preview canvas
previewCtx.save(); previewCtx.save();
previewCtx.clearRect(0,0,canvas.width, canvas.height); previewCtx.clearRect(0,0,canvas.width, canvas.height);
previewCtx.restore(); previewCtx.restore();
// also make new Image, otherwise the previously cached preview can be redrawn with move up/down or twist left/right // also make new Image, otherwise the previously cached preview can be redrawn with move up/down or twist left/right
doodleImageCapture = new Image(); doodleImageCapture = new Image();
// reset height and rotation to default values // reset height and rotation to default values
numLayers = previewDefaults.numLayers; // current number of preview layers numLayers = previewDefaults.numLayers; // current number of preview layers
rStep = previewDefaults.rotation; // Math.PI/180; //Math.PI/40; // rStep = previewDefaults.rotation; // Math.PI/180; //Math.PI/40; //
} }
function oopsUndo() { function oopsUndo() {
// console.log("f:oopsUndo()"); // console.log("f:oopsUndo()");
_points.pop(); _points.pop();
if (clientInfo.isSmartphone) { if (clientInfo.isSmartphone) {
// do not recalc the whole preview's bounds during undo if client device is a smartphone // do not recalc the whole preview's bounds during undo if client device is a smartphone
redrawDoodle(false); redrawDoodle(false);
} else { } else {
// recalc the whole preview's bounds during if client device is not a smartphone // recalc the whole preview's bounds during if client device is not a smartphone
redrawDoodle(true); redrawDoodle(true);
} }
redrawPreview(); redrawPreview();
} }
function previewUp(redrawLess) { function previewUp(redrawLess) {
// console.log("f:previewUp()"); // console.log("f:previewUp()");
if (numLayers < maxNumLayers) { if (numLayers < maxNumLayers) {
numLayers++; numLayers++;
} }
setSketchModified(true); setSketchModified(true);
// redrawPreview(redrawLess); // redrawPreview(redrawLess);
redrawRenderedPreview(redrawLess); redrawRenderedPreview(redrawLess);
} }
function previewDown(redrawLess) { function previewDown(redrawLess) {
// console.log("f:previewDown()"); // console.log("f:previewDown()");
if (numLayers > minNumLayers) { if (numLayers > minNumLayers) {
numLayers--; numLayers--;
} }
setSketchModified(true); setSketchModified(true);
// redrawPreview(redrawLess); // redrawPreview(redrawLess);
redrawRenderedPreview(redrawLess); redrawRenderedPreview(redrawLess);
} }
function previewTwistLeft(redrawLess) { function previewTwistLeft(redrawLess) {
previewTwist(-twistIncrement,true) previewTwist(-twistIncrement,true)
@ -320,25 +319,23 @@ function previewTwistRight(redrawLess) {
} }
function previewTwist(increment,redrawLess) { function previewTwist(increment,redrawLess) {
console.log("previewTwist: ",increment); console.log("previewTwist: ",increment);
if (redrawLess == undefined) redrawLess = false; if (redrawLess == undefined) redrawLess = false;
rStep += increment; rStep += increment;
if(rStep < -previewRotationLimit) rStep = -previewRotationLimit; if(rStep < -previewRotationLimit) rStep = -previewRotationLimit;
else if(rStep > previewRotationLimit) rStep = previewRotationLimit; else if(rStep > previewRotationLimit) rStep = previewRotationLimit;
redrawRenderedPreview(redrawLess); redrawRenderedPreview(redrawLess);
setSketchModified(true); setSketchModified(true);
} }
function resetTwist() { function resetTwist() {
rStep = 0; rStep = 0;
redrawRenderedPreview(); redrawRenderedPreview();
setSketchModified(true); setSketchModified(true);
} }
function update() { function update() {
setState(printer.state,printer.hasControl); setState(printer.state,printer.hasControl);
thermometer.update(printer.temperature, printer.targetTemperature); thermometer.update(printer.temperature, printer.targetTemperature);
@ -371,54 +368,60 @@ function setState(newState,newHasControl) {
// thermometer // thermometer
switch(newState) { switch(newState) {
case Printer.IDLE_STATE: /* fall-through */ case Printer.IDLE_STATE: /* fall-through */
case Printer.BUFFERING_STATE: /* fall-through */ case Printer.BUFFERING_STATE: /* fall-through */
case Printer.PRINTING_STATE: /* fall-through */ case Printer.PRINTING_STATE: /* fall-through */
case Printer.STOPPING_STATE: case Printer.STOPPING_STATE:
thermometer.show(); thermometer.show();
break; break;
default: default:
thermometer.hide(); thermometer.hide();
break; break;
} }
// progress indicator // progress indicator
switch(newState) { switch(newState) {
case Printer.PRINTING_STATE: case Printer.PRINTING_STATE:
progressbar.show(); progressbar.show();
break; break;
default: default:
progressbar.hide(); progressbar.hide();
break; break;
} }
/* settings button */ /* settings button */
switch(newState) { switch(newState) {
case Printer.IDLE_STATE: case Printer.CONNECTING_STATE: /* fall-through */
btnSettings.enable(); case Printer.IDLE_STATE:
break; btnSettings.enable();
case Printer.WIFIBOX_DISCONNECTED_STATE: /* fall-through */ break;
case Printer.BUFFERING_STATE: /* fall-through */ case Printer.WIFIBOX_DISCONNECTED_STATE: /* fall-through */
case Printer.PRINTING_STATE: /* fall-through */ case Printer.BUFFERING_STATE: /* fall-through */
case Printer.STOPPING_STATE: case Printer.PRINTING_STATE: /* fall-through */
btnSettings.disable(); case Printer.STOPPING_STATE:
break; btnSettings.disable();
default: break;
btnSettings.enable(); default:
break; btnSettings.enable();
} break;
}
/* save, next and prev buttons */ /* save, next and prev buttons */
switch(newState) { switch(newState) {
case Printer.WIFIBOX_DISCONNECTED_STATE: case Printer.WIFIBOX_DISCONNECTED_STATE:
btnPrevious.disable(); btnPrevious.disable();
btnNext.disable() btnNext.disable()
btnSave.disable(); btnSave.disable();
break; break;
default: default:
updatePrevNextButtonState(); updatePrevNextButtonState();
if (isModified) btnSave.enable(); if (isModified) btnSave.enable();
break; break;
}
if(connectingHintDelay && newState != Printer.CONNECTING_STATE) {
clearTimeout(connectingHintDelay);
connectingHintDelay = null;
} }
if(newState == Printer.WIFIBOX_DISCONNECTED_STATE) { if(newState == Printer.WIFIBOX_DISCONNECTED_STATE) {
@ -427,12 +430,22 @@ function setState(newState,newHasControl) {
message.set("Connected to WiFi box",Message.INFO,true); message.set("Connected to WiFi box",Message.INFO,true);
} else if(newState == Printer.DISCONNECTED_STATE) { } else if(newState == Printer.DISCONNECTED_STATE) {
message.set("Printer disconnected",Message.WARNING,true); message.set("Printer disconnected",Message.WARNING,true);
} else if(newState == Printer.CONNECTING_STATE) {
message.set("Printer connecting...",Message.INFO,false);
if (prevState != Printer.CONNECTING_STATE) { //enable 'watchdog' if we entered from a different state
clearTimeout(connectingHintDelay);
connectingHintDelay = setTimeout(function() {
message.set("Printer still not connected, did you<br/>select the correct printer type?", Message.WARNING, false);
connectingHintDelay = null;
}, connectingHintDelayTime);
}
} else if(prevState == Printer.DISCONNECTED_STATE && newState == Printer.IDLE_STATE || } else if(prevState == Printer.DISCONNECTED_STATE && newState == Printer.IDLE_STATE ||
prevState == Printer.UNKNOWN_STATE && newState == Printer.IDLE_STATE) { prevState == Printer.UNKNOWN_STATE && newState == Printer.IDLE_STATE ||
prevState == Printer.CONNECTING_STATE && newState == Printer.IDLE_STATE) {
message.set("Printer connected",Message.INFO,true); message.set("Printer connected",Message.INFO,true);
console.log(" preheat: ",settings["printer.heatup.enabled"]); console.log(" preheat: ",settings["printer.heatup.enabled"]);
if(settings["printer.heatup.enabled"]) { if(settings["printer.heatup.enabled"]) {
// HACK: we delay the preheat because the driver needs time to connect // HACK: we delay the preheat because the makerbot driver needs time to connect
clearTimeout(preheatDelay); clearTimeout(preheatDelay);
preheatDelay = setTimeout(printer.preheat,preheatDelayTime); // retry after delay preheatDelay = setTimeout(printer.preheat,preheatDelayTime); // retry after delay
} }

View File

@ -7,61 +7,80 @@
*/ */
function UpdatePanel() { function UpdatePanel() {
var _form = new FormPanel();
this.wifiboxURL; this.wifiboxURL;
this.element; this.element;
this.statusCheckInterval = 1000; this.statusCheckInterval = 1000;
this.statusCheckDelayer; // setTimout instance this.statusCheckDelayer; // setTimout instance
this.installedDelay = 90*1000; // Since we can't retrieve status during installation we show the installed text after a fixed delay this.installedDelay = 90*1000; // Since we can't retrieve status during installation we show the installed text after a fixed delay
this.installedDelayer; // setTimout instance this.installedDelayer; // setTimout instance
this.retryDelay = 1000; this.retryDelay = 1000;
this.retryDelayer; // setTimout instance this.retryDelayer; // setTimout instance
//this.timeoutTime = 3000; //this.timeoutTime = 3000;
this.canUpdate = false; this.canUpdate = false;
this.currentVersion = ""; this.currentVersion = "";
this.newestVersion; this.newestVersion;
this.currentReleaseDate;
this.newestReleaseDate;
this.progress; this.progress;
this.imageSize; this.imageSize;
var _inAccessPointMode; var _inAccessPointMode;
// states from api, see Doodle3D firmware src/script/d3d-updater.lua // states from api, see Doodle3D firmware src/script/d3d-updater.lua
UpdatePanel.NONE = 1; // default state UpdatePanel.NONE = 1; // default state
UpdatePanel.DOWNLOADING = 2; UpdatePanel.DOWNLOADING = 2;
UpdatePanel.DOWNLOAD_FAILED = 3; UpdatePanel.DOWNLOAD_FAILED = 3;
UpdatePanel.IMAGE_READY = 4; // download successfull and checked UpdatePanel.IMAGE_READY = 4; // download successful and checked
UpdatePanel.INSTALLING = 5; UpdatePanel.INSTALLING = 5;
UpdatePanel.INSTALLED = 6; UpdatePanel.INSTALLED = 6;
UpdatePanel.INSTALL_FAILED = 7; UpdatePanel.INSTALL_FAILED = 7;
this.state; // update state from api this.state; // update state from api
this.stateText = ""; // update state text from api this.stateText = ""; // update state text from api
var self = this; var self = this;
this.init = function(wifiboxURL,updatePanelElement) { this.init = function(wifiboxURL,updatePanelElement) {
_form.init(wifiboxURL,wifiboxURL,updatePanelElement);
this.wifiboxURL = wifiboxURL; this.wifiboxURL = wifiboxURL;
this.element = updatePanelElement; this.element = updatePanelElement;
this.retainCheckbox = this.element.find("#retainConfiguration"); this.retainCheckbox = this.element.find("#retainConfiguration");
this.includeBetasCheckbox = this.element.find("#includeBetas");
this.btnUpdate = this.element.find("#update"); this.btnUpdate = this.element.find("#update");
this.statusDisplay = this.element.find("#updateState"); this.statusDisplay = this.element.find("#updateState");
this.infoDisplay = this.element.find("#updateInfo"); this.infoDisplay = this.element.find("#updateInfo");
this.retainCheckbox.change(this.retainChanged); this.retainCheckbox.change(this.retainChanged);
this.includeBetasCheckbox.change(this.includeBetasChanged);
this.btnUpdate.click(this.update); this.btnUpdate.click(this.update);
this.checkStatus(false); this.checkStatus(false);
} }
this.retainChanged = function(e) { this.retainChanged = function(e) {
//console.log("UpdatePanel:retainChanged"); //console.log("UpdatePanel:retainChanged");
//this call ensures that the update button gets enabled if (!retainChanged && !canUpdate)
self.setState(self.state,true); self.setState(self.state,true);
} }
this.includeBetasChanged = function() {
//console.log("UpdatePanel:includeBetasChanged");
_form.saveSettings(_form.readForm(),function(validated, data) {
if(validated) self.checkStatus(false);
});
}
this.update = function() { this.update = function() {
console.log("UpdatePanel:update"); console.log("UpdatePanel:update");
self.downloadUpdate(); self.downloadUpdate();
} }
this.downloadUpdate = function() { this.downloadUpdate = function() {
console.log("UpdatePanel:downloadUpdate"); console.log("UpdatePanel:downloadUpdate");
$.ajax({ $.ajax({
@ -77,6 +96,7 @@ function UpdatePanel() {
self.setState(UpdatePanel.DOWNLOADING); self.setState(UpdatePanel.DOWNLOADING);
self.startCheckingStatus(); self.startCheckingStatus();
} }
this.installUpdate = function() { this.installUpdate = function() {
console.log("UpdatePanel:installUpdate"); console.log("UpdatePanel:installUpdate");
@ -103,17 +123,20 @@ function UpdatePanel() {
self.installedDelayer = setTimeout(function() { self.setState(UpdatePanel.INSTALLED) },self.installedDelay); self.installedDelayer = setTimeout(function() { self.setState(UpdatePanel.INSTALLED) },self.installedDelay);
} }
this.startCheckingStatus = function() { this.startCheckingStatus = function() {
clearTimeout(self.statusCheckDelayer); clearTimeout(self.statusCheckDelayer);
clearTimeout(self.retryDelayer); clearTimeout(self.retryDelayer);
self.statusCheckDelayer = setTimeout(function() { self.checkStatus(true) },self.statusCheckInterval); self.statusCheckDelayer = setTimeout(function() { self.checkStatus(true) },self.statusCheckInterval);
} }
this.stopCheckingStatus = function() { this.stopCheckingStatus = function() {
clearTimeout(self.statusCheckDelayer); clearTimeout(self.statusCheckDelayer);
clearTimeout(self.retryDelayer); clearTimeout(self.retryDelayer);
} }
this.checkStatus = function(keepChecking) { this.checkStatus = function(keepChecking) {
if (!communicateWithWifibox) return; if (!communicateWithWifibox) return;
$.ajax({ $.ajax({
url: self.wifiboxURL + "/update/status", url: self.wifiboxURL + "/update/status",
type: "GET", type: "GET",
@ -136,6 +159,8 @@ function UpdatePanel() {
if(response.status != "error") { if(response.status != "error") {
var data = response.data; var data = response.data;
self.handleStatusData(data); self.handleStatusData(data);
} else {
console.log("API update/status call returned an error: '" + response.msg + "'");
} }
} }
}).fail(function() { }).fail(function() {
@ -147,13 +172,19 @@ function UpdatePanel() {
}); });
} }
this.handleStatusData = function(data) { this.handleStatusData = function(data) {
//console.log("UpdatePanel:handleStatusData"); //console.log("UpdatePanel:handleStatusData");
//status texts and button state might have to be updated if the newest version changes (e.g., after (un)ticking include betas checkbox)
var refreshUI = (self.newestVersion != data.newest_version);
self.canUpdate = data.can_update; self.canUpdate = data.can_update;
if(self.currentVersion != data.current_version || self.newestVersion != data.newest_version) { if(self.currentVersion != data.current_version || self.newestVersion != data.newest_version) {
self.currentVersion = data.current_version; self.currentVersion = data.current_version;
self.newestVersion = data.newest_version; self.newestVersion = data.newest_version;
self.currentReleaseDate = data.current_release_date; // not always available (for older versions)
self.newestReleaseDate = data.newest_release_date; // not always available (for older versions)
self.updateInfoDisplay(); self.updateInfoDisplay();
} }
@ -161,7 +192,7 @@ function UpdatePanel() {
self.progress = data.progress; // not always available self.progress = data.progress; // not always available
self.imageSize = data.image_size; // not always available self.imageSize = data.image_size; // not always available
self.setState(data.state_code); self.setState(data.state_code, refreshUI);
switch(this.state){ switch(this.state){
case UpdatePanel.IMAGE_READY: case UpdatePanel.IMAGE_READY:
@ -169,6 +200,7 @@ function UpdatePanel() {
break; break;
} }
} }
this.setState = function(newState,refresh) { this.setState = function(newState,refresh) {
//console.log("UpdatePanel:setState"); //console.log("UpdatePanel:setState");
if(!refresh && this.state == newState) return; if(!refresh && this.state == newState) return;
@ -198,20 +230,32 @@ function UpdatePanel() {
break; break;
default: default:
self.btnUpdate.attr("disabled", true); self.btnUpdate.attr("disabled", true);
break; break;
} }
} else { } else {
self.btnUpdate.attr("disabled", true); self.btnUpdate.attr("disabled", true);
} }
this.updateStatusDisplay(); this.updateStatusDisplay();
} }
this.updateStatusDisplay = function() { this.updateStatusDisplay = function() {
var text = ""; var text = "";
if(self.newestVersion != undefined) { if(self.newestVersion != undefined) {
switch(this.state){ switch(this.state){
case UpdatePanel.NONE: case UpdatePanel.NONE:
if(self.canUpdate) { if(self.canUpdate) {
text = "Update(s) available."; var currIsBeta = self.versionIsBeta(self.currentVersion);
var newIsBeta = self.versionIsBeta(self.newestVersion);
var relIsNewer = (self.newestReleaseDate && self.currentReleaseDate) ? (self.newestReleaseDate - self.currentReleaseDate > 0) : true;
if (!newIsBeta) {
if (relIsNewer) text = "Update available.";
else text = "You can switch back to the latest stable release."; //this case is always a beta->stable 'downgrade'
} else {
//NOTE: actually, an older beta will never be presented as update by the API
var prefixText = currIsBeta ? "A" : (relIsNewer ? "A newer" : "An older");
text = prefixText + " beta release is available.";
}
} else { } else {
text = "You're up to date."; text = "You're up to date.";
} }
@ -229,8 +273,8 @@ function UpdatePanel() {
text = "Installing update... (will take a minute)"; text = "Installing update... (will take a minute)";
break; break;
case UpdatePanel.INSTALLED: case UpdatePanel.INSTALLED:
text = "Update complete, please reconnect by connecting your device to the access point of your WiFi box and going to <a href='http://draw.doodle3d.com'>draw.doodle3d.com</a>"; //text = "Update complete, please reconnect by connecting your device to the access point of your WiFi box and going to <a href='http://draw.doodle3d.com'>draw.doodle3d.com</a>";
//text = "Update complete, please <a href='javascript:location.reload(true);'>refresh Page</a>."; text = "Update complete, please <a href='javascript:location.reload(true);'>refresh Page</a>.";
break; break;
case UpdatePanel.INSTALL_FAILED: case UpdatePanel.INSTALL_FAILED:
text = "Installing update failed."; text = "Installing update failed.";
@ -245,18 +289,36 @@ function UpdatePanel() {
} }
this.statusDisplay.html(text); this.statusDisplay.html(text);
} }
this.updateInfoDisplay = function() { this.updateInfoDisplay = function() {
var html = 'Current version: ' + self.currentVersion + var html = 'Current version: ' + self.currentVersion;
' (<a target="d3d-curr-relnotes" href="ReleaseNotes.html">release notes</a>). '; if (self.currentReleaseDate) html += '; released: ' + self.formatDate(self.currentReleaseDate);
html += ' (<a target="d3d-curr-relnotes" href="ReleaseNotes.html">release notes</a>).';
if(self.canUpdate) { if(self.canUpdate) {
html += 'Latest version: ' + self.newestVersion + html += '<br/>Latest version: ' + self.newestVersion;
' (<a target="d3d-new-relnotes" href="http://doodle3d.com/updates/images/ReleaseNotes.md">release notes</a>).'; if (self.newestReleaseDate) html += '; released: ' + self.formatDate(self.newestReleaseDate);
html += ' (<a target="d3d-new-relnotes" href="http://doodle3d.com/updates/images/ReleaseNotes.md">release notes</a>).';
} }
self.infoDisplay.html(html); self.infoDisplay.html(html);
} }
this.setInAccessPointMode = function(inAccessPointMode) { this.setInAccessPointMode = function(inAccessPointMode) {
_inAccessPointMode = inAccessPointMode; _inAccessPointMode = inAccessPointMode;
self.updateStatusDisplay(); self.updateStatusDisplay();
} }
this.formatDate = function(ts) {
if (!ts || ts.length != 8 || !/^[0-9]+$/.test(ts)) return null;
var fields = [ ts.substr(0, 4), ts.substr(4, 2), ts.substr(6, 2) ];
if (!fields || fields.length != 3 || fields[1] > 12) return null;
var abbrMonths = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Sep', 'Aug', 'Oct', 'Nov', 'Dec' ];
return abbrMonths[fields[1] - 1] + " " + fields[2] + ", " + fields[0];
}
this.versionIsBeta = function(version) {
return version ? /.*-.*/g.test(version) : null;
}
} }

View File

@ -1,5 +1,6 @@
#message { #message {
position: absolute; position: absolute;
text-align: right;
top: 0; top: 0;
right: 0; right: 0;

View File

@ -1,143 +1,172 @@
form { form {
margin: 10px; margin: 10px;
max-width: 600px; max-width: 600px;
} }
form input { form input {
margin: 1px; margin: 1px;
} }
body,th,td { body,th,td {
font-family: Helvetica, Arial, "Nimbus Sans L", sans-serif; font-family: Helvetica, Arial, "Nimbus Sans L", sans-serif;
font-size: 13px; font-size: 13px;
} }
.settingsContainer { .settingsContainer {
position:relative; position: relative;
/*min-width: 370px;*/ /*min-width: 370px;*/
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
/*form#settingsForm {*/ /*form#settingsForm {*/
/*width: 100% auto;*/ /*width: 100% auto;*/
/*}*/ /*}*/
form fieldset { form fieldset {
max-width: 600px; max-width: 600px;
border: 1px solid rgb(187, 187, 187); border: 1px solid rgb(187, 187, 187);
border-radius: 5px; border-radius: 5px;
-webkit-border-radius: 5px; -webkit-border-radius: 5px;
-moz-border-radius: 5px; -moz-border-radius: 5px;
margin-bottom: 20px; margin-bottom: 20px;
padding: 8px; padding: 8px;
/*padding-right: 8px;*/ /*padding-right: 8px;*/
} }
form fieldset fieldset{
form fieldset fieldset {
max-width: 580px; max-width: 580px;
margin: 15px 0 5px 0; margin: 15px 0 5px 0;
clear: left; clear: left;
float: left; float: left;
} }
form fieldset.collapsed { form fieldset.collapsed {
border-radius: 0; border-radius: 0;
-webkit-border-radius: 0; -webkit-border-radius: 0;
-moz-border-radius: 0; -moz-border-radius: 0;
border-width: 1px 0 0 0; border-width: 1px 0 0 0;
float:none; float: none;
} }
form fieldset.collapsible { form fieldset.collapsible {
padding: 0; padding: 0;
} }
form fieldset.collapsible div{
form fieldset.collapsible div {
margin: 8px; margin: 8px;
} }
form fieldset legend { form fieldset legend {
margin-left: 10px; margin-left: 10px;
font-weight: bold; font-weight: bold;
} }
form fieldset.collapsible legend { form fieldset.collapsible legend {
padding-left: 10px; padding-left: 10px;
cursor: pointer; cursor: pointer;
} }
form fieldset.expanded legend { form fieldset.expanded legend {
background: transparent url(../img/buttons/expanded.gif) no-repeat center left; background: transparent url(../img/buttons/expanded.gif) no-repeat
center left;
} }
form fieldset.collapsed legend { form fieldset.collapsed legend {
background: transparent url(../img/buttons/collapsed.gif) no-repeat center left; background: transparent url(../img/buttons/collapsed.gif) no-repeat
center left;
} }
form label { form label {
min-width: 150px; min-width: 150px;
display: block; display: block;
float: left; float: left;
margin: 1px 0 0 0; margin: 1px 0 0 0;
clear: left; clear: left;
} }
form div { form div {
float: left; float: left;
} }
form input[type="text"], form input[type="number"], form input[type="password"] {
border: 1px solid rgb(144, 192, 255); form input[type="text"],form input[type="number"], form input[type="password"]
margin-right: 5px; {
-webkit-border-radius: 4px; border: 1px solid rgb(144, 192, 255);
margin-right: 5px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px; -moz-border-radius: 4px;
border-radius: 4px; border-radius: 4px;
} }
form input[type="text"].small, form input[type="number"].small, form input[type="password"].small {
width: 50px; form input[type="text"].small,form input[type="number"].small, form input[type="password"].small
{
width: 50px;
} }
form input[type="text"].large, form input[type="number"].large, form input[type="password"].large {
width: 250px; form input[type="text"].large,form input[type="number"].large, form input[type="password"].large
{
width: 250px;
} }
form input[type="radio"] { form input[type="radio"] {
margin: 4px 4px 0 0; margin: 4px 4px 0 0;
} }
form textarea { form textarea {
border: 1px solid rgb(144, 192, 255); border: 1px solid rgb(144, 192, 255);
-webkit-border-radius: 5px; -webkit-border-radius: 5px;
-moz-border-radius: 5px; -moz-border-radius: 5px;
border-radius: 5px; border-radius: 5px;
} }
form .startgcode_left { form .startgcode_left {
float:left; float: left;
margin-right: 20px; margin-right: 20px;
} }
form textarea.gcode { form textarea.gcode {
width: 252px; width: 252px;
/*max-width: 262px;*/ /*max-width: 262px;*/
/*min-width: 200px;*/ /*min-width: 200px;*/
height: 150px; height: 150px;
} }
form small { form small {
margin: 3px 0 0 0; margin: 3px 0 0 0;
display: block; display: block;
clear: left; clear: left;
} }
form .button { form .button {
display: inline-block; display: inline-block;
} }
form #passwordLabel, form #password { form #passwordLabel,form #password {
display: none; display: none;
} }
form input.error, form textarea.error, form select.error { form input.error, form textarea.error, form select.error {
border: #f00 solid 2px; border: #f00 solid 2px;
} }
form .errorMsg { form .errorMsg {
color: #f00; color: #f00;
margin: 0 0 0 1em; margin: 0 0 0 1em;
} }
form .intro { form .intro {
margin: 0 0 0.5em 0; margin: 0 0 0.5em 0;
} }
form dl { form dl {
margin: 0.5em 0 0 0; margin: 0.5em 0 0 0;
} }
form dl dt { form dl dt {
float: left; float: left;
font-style: italic; font-style: italic;
width: 10em; width: 10em;
} }
#updatePanel #retainConfigurationLabel {
#updatePanel #retainConfigurationLabel, #updatePanel #includeBetasLabel {
display: inline; display: inline;
float: none; float: none;
} }

View File

@ -5,10 +5,13 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="mobile-web-app-capable" content="yes" />
<meta id="Viewport" name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no,minimal-ui">
<link rel="icon" type="image/ico" href="./favicon_alt.ico"/> <link rel="icon" type="image/ico" href="./favicon_alt.ico"/>
<link rel="apple-touch-icon-precomposed" href="./img/webpage_icons/apple-touch-icon-144x144-precomposed.png"/> <link rel="apple-touch-icon-precomposed" href="./img/webpage_icons/apple-touch-icon-144x144-precomposed.png"/>
<link rel="apple-touch-icon-precomposed" href="./img/webpage_icons/apple-touch-icon-144x144-precomposed.png" sizes="144x144" /> <link rel="apple-touch-icon-precomposed" href="./img/webpage_icons/apple-touch-icon-144x144-precomposed.png" sizes="144x144" />
<meta id="Viewport" name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<link href="css/styles.min.css" rel="stylesheet" media="screen"> <link href="css/styles.min.css" rel="stylesheet" media="screen">
<link href="css/debug.min.css" rel="stylesheet" media="screen"> <link href="css/debug.min.css" rel="stylesheet" media="screen">
@ -63,8 +66,6 @@
</div> </div>
<div id="message"></div>
<!-- center panel --> <!-- center panel -->
<div id="centerpanel"> <div id="centerpanel">
@ -153,6 +154,8 @@
</div> </div>
</div> </div>
</div> </div>
<div id="message"></div>
</div> </div>
<div id="portrait"> <div id="portrait">

View File

@ -165,8 +165,9 @@
<fieldset id="updatePanel"> <fieldset id="updatePanel">
<legend>Update</legend> <legend>Update</legend>
<input id="retainConfiguration" type="checkbox" name="" value="retainConfiguration" checked="true"> <label for="retainConfiguration" id="retainConfigurationLabel">Preserve personal sketches and settings</label> <input id="retainConfiguration" type="checkbox" name="" value="retainConfiguration" checked="true"> <label for="retainConfiguration" id="retainConfigurationLabel">Preserve personal sketches and settings</label><br/>
<br/><br/> <input id="includeBetas" type="checkbox" name="doodle3d.update.includeBetas" value="includeBetas"> <label for="includeBetas" id="includeBetasLabel">Include beta releases (<a target="beta-info" href="http://doodle3d.com/help/beta">read more</a>)</label><br/>
<br/>
<input type="button" name="update" value="Update" class="button" id="update"/> <input type="button" name="update" value="Update" class="button" id="update"/>
<span id="updateState"></span><br/> <span id="updateState"></span><br/>
<small id="updateInfo"></small> <small id="updateInfo"></small>