
Merged in chrishamm's changes to Network, PrintMonitor, and his support for firmware updates from SD card Fixed print monitor issue that threw out the layer count and time estimates when there was an initial extruder priming move in the start gcode
2516 lines
77 KiB
JavaScript
2516 lines
77 KiB
JavaScript
/* Interface logic for the Duet Web Control v1.10
|
|
*
|
|
* written by Christian Hammacher
|
|
*
|
|
* licensed under the terms of the GPL v2
|
|
* see http://www.gnu.org/licenses/gpl-2.0.html
|
|
*/
|
|
|
|
var maxTemperatureSamples = 1000;
|
|
var probeSlowDownColor = "#FFFFE0", probeTriggerColor = "#FFF0F0";
|
|
|
|
var tempChart;
|
|
var tempChartOptions = {
|
|
colors: ["#0000FF", "#FF0000", "#00DD00", "#FFA000", "#FF00FF", "#337AB7", "#00FFFF", "#000000"],
|
|
grid: {
|
|
borderWidth: 0
|
|
},
|
|
xaxis: {
|
|
show: false
|
|
},
|
|
yaxis: {
|
|
min: 0,
|
|
max: 280
|
|
}
|
|
};
|
|
var tempChartPadding = 15;
|
|
|
|
var printChart;
|
|
var printChartOptions = {
|
|
colors: ["#EDC240"],
|
|
grid: {
|
|
borderWidth: 0,
|
|
hoverable: true,
|
|
clickable: true
|
|
},
|
|
pan: {
|
|
interactive: true
|
|
},
|
|
series: {
|
|
lines: {
|
|
show: true
|
|
},
|
|
points: {
|
|
show: true
|
|
}
|
|
},
|
|
xaxis: {
|
|
min: 1,
|
|
tickDecimals: 0,
|
|
},
|
|
yaxis: {
|
|
min: 0,
|
|
max: 30,
|
|
ticks: 5,
|
|
tickDecimals: 0,
|
|
tickFormatter: function(val) { if (!val) { return ""; } else { return val + "s"; } }
|
|
},
|
|
zoom: {
|
|
interactive: true
|
|
}
|
|
};
|
|
|
|
var webcamUpdating = false;
|
|
|
|
|
|
$(document).ready(function() {
|
|
disableControls();
|
|
|
|
resetGuiData();
|
|
updateGui();
|
|
|
|
$("#web_version").append(", JS: " + jsVersion);
|
|
$("#text_config").textareaAutoSize();
|
|
|
|
loadSettings(false);
|
|
});
|
|
|
|
function settingsLoaded() {
|
|
applySettings();
|
|
|
|
$.ajax("language.xml", {
|
|
type: "GET",
|
|
dataType: "xml",
|
|
global: false,
|
|
error: function() {
|
|
pageLoadComplete();
|
|
},
|
|
success: function(response) {
|
|
translationData = response;
|
|
|
|
if (translationData.children == undefined)
|
|
{
|
|
// Internet Explorer and Edge cannot deal with XML files in the way we want.
|
|
// Disable translations for those browsers.
|
|
translationData = undefined;
|
|
$("#dropdown_language, #label_language").addClass("hidden");
|
|
} else {
|
|
$("#dropdown_language ul > li:not(:first-child)").remove();
|
|
for(var i=0; i<translationData.children[0].children.length; i++) {
|
|
var id = translationData.children[0].children[i].tagName;
|
|
var name = translationData.children[0].children[i].attributes["name"].value;
|
|
$("#dropdown_language ul").append( '<li><a data-language="' + id + '" href="#">' + name + '</a></li>');
|
|
if (settings.language == id) {
|
|
$("#btn_language > span:first-child").text(name);
|
|
}
|
|
}
|
|
|
|
translatePage();
|
|
}
|
|
|
|
pageLoadComplete();
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
function pageLoadComplete() {
|
|
log("info", "<strong>" + T("Page Load complete!") + "</strong>");
|
|
|
|
if (settings.autoConnect) {
|
|
// Users might want to connect automatically once the page has loaded
|
|
connect(sessionPassword, true);
|
|
}
|
|
}
|
|
|
|
function enableControls() {
|
|
$("nav input, #div_heaters input, #main_content input").prop("disabled", false); // Generic inputs
|
|
$("#page_tools label").removeClass("disabled"); // and on Settings page
|
|
|
|
$(".btn-emergency-stop, .gcode-input button[type=submit], .gcode").removeClass("disabled"); // Navbar
|
|
$(".bed-temp, .gcode, .heater-temp, .btn-upload").removeClass("disabled"); // List items and Upload buttons
|
|
|
|
$("#mobile_home_buttons button, #btn_homeall, #table_move_head a").removeClass("disabled"); // Move buttons
|
|
$("#panel_extrude label.btn, #panel_extrude button").removeClass("disabled"); // Extruder Control
|
|
$("#panel_control_misc label.btn").removeClass("disabled"); // ATX Power
|
|
$("#slider_fan_control").slider("enable"); // Fan Control
|
|
|
|
$("#page_print .checkbox").removeClass("disabled"); // Print Control
|
|
$("#slider_fan_print").slider("enable"); // Fan Control
|
|
$("#slider_speed").slider("enable"); // Speed Factor
|
|
for(var extr=1; extr<=6; extr++) {
|
|
$("#slider_extr_" + extr).slider("enable"); // Extrusion Factors
|
|
}
|
|
|
|
$(".online-control").removeClass("hidden"); // G-Code/Macro Files
|
|
}
|
|
|
|
function disableControls() {
|
|
$("nav input, #div_heaters input, #main_content input").prop("disabled", true); // Generic inputs
|
|
$("#page_general input, #page_listitems input").prop("disabled", false); // ... except ...
|
|
$("#page_tools label").addClass("disabled"); // ... for Settings
|
|
|
|
$(".btn-emergency-stop, .gcode-input button[type=submit], .gcode").addClass("disabled"); // Navbar
|
|
$("#extruder_drives").addClass("disabled"); // Info Panels
|
|
$(".bed-temp, .gcode, .heater-temp, .btn-upload").addClass("disabled"); // List items and Upload buttons
|
|
|
|
$("#mobile_home_buttons button, #btn_homeall, #table_move_head a").addClass("disabled"); // Move buttons
|
|
$("#panel_extrude label.btn, #panel_extrude button").addClass("disabled"); // Extruder Control
|
|
$("#panel_control_misc label.btn").addClass("disabled"); // ATX Power
|
|
$("#slider_fan_control").slider("disable"); // Fan Control
|
|
|
|
$("#btn_pause, #page_print .checkbox").addClass("disabled"); // Print Control
|
|
$("#slider_fan_print").slider("disable"); // Fan Control
|
|
$("#slider_speed").slider("disable"); // Speed Factor
|
|
for(var extr=1; extr<=6; extr++) {
|
|
$("#slider_extr_" + extr).slider("disable"); // Extrusion Factors
|
|
}
|
|
|
|
$(".online-control").addClass("hidden"); // G-Code/Macro Files
|
|
}
|
|
|
|
function updateGui() {
|
|
// Visibility for Heater Temperatures
|
|
|
|
if (heatedBed) { // Heated Bed
|
|
$("#tr_bed").removeClass("hidden");
|
|
} else {
|
|
$("#tr_bed").addClass("hidden");
|
|
}
|
|
if (chamber) { // Chamber
|
|
$("#tr_chamber").removeClass("hidden");
|
|
} else {
|
|
$("#tr_chamber").addClass("hidden");
|
|
}
|
|
for(var i=1; i<=6; i++) { // Heads (Heaters)
|
|
if (i <= numHeads) {
|
|
$("#tr_head_" + i).removeClass("hidden");
|
|
} else {
|
|
$("#tr_head_" + i).addClass("hidden");
|
|
}
|
|
}
|
|
|
|
// Visibility for Extruder Drive columns
|
|
|
|
for(var i=1; i<=6; i++) {
|
|
if (i <= numExtruderDrives) {
|
|
$(".extr-" + i).removeClass("hidden").css("border-right", "");
|
|
$("#slider_extr_" + i).slider("relayout");
|
|
} else {
|
|
$(".extr-" + i).addClass("hidden").css("border-right", "");
|
|
}
|
|
}
|
|
if (numExtruderDrives > 0) {
|
|
$(".extr-" + numExtruderDrives).css("border-right", "0px");
|
|
$("#row_status_2").removeClass("hidden");
|
|
} else {
|
|
$("#row_status_2").addClass("hidden");
|
|
}
|
|
|
|
// Add Zero Extruder Drive buttons
|
|
|
|
if (isConnected) {
|
|
$("#extruder_drives").removeClass("disabled");
|
|
$("#ul_extruder_dropdown").html('<li><a href="#" class="zero-extruder" data-target="all">' + T("Zero All Drives") + '</li><li class="divider"></li>');
|
|
for(var i=1; i<= numExtruderDrives; i++) {
|
|
$("#ul_extruder_dropdown").append('<li><a href="#" class="zero-extruder" data-target="' + i + '">' + T("Zero Extruder Drive {0}", i) + '</a></li>');
|
|
}
|
|
|
|
$(".zero-extruder").off("click").click(function(e) {
|
|
if (lastStatusResponse != undefined) {
|
|
var gcode = "G92 E", target = $(this).data("target");
|
|
for(var i=1; i<=numExtruderDrives; i++) {
|
|
if (target != "all" && target != i) {
|
|
gcode += lastStatusResponse.coords.extr[i - 1];
|
|
} else {
|
|
gcode += "0";
|
|
}
|
|
|
|
if (i < numExtruderDrives) {
|
|
gcode += ":";
|
|
}
|
|
}
|
|
sendGCode(gcode);
|
|
}
|
|
e.preventDefault();
|
|
});
|
|
}
|
|
|
|
// Do some rearrangement for the panels if we have less than or exactly three extruder drives
|
|
|
|
if (numExtruderDrives <= 3) {
|
|
$(".div-head-temp").removeClass("hidden-sm");
|
|
$("#col_extr_totals, #td_extr_total").addClass("hidden");
|
|
for(var i=1; i<=3; i++) {
|
|
$("th.extr-" + i).html(T("Drive " + i));
|
|
$("#row_status_2 .extr-" + i).removeClass("hidden-md");
|
|
}
|
|
$("#div_heaters").removeClass("col-sm-5").addClass("col-sm-6");
|
|
$("#div_temp_chart").removeClass("col-lg-3").addClass("col-lg-5");
|
|
$("#div_status").removeClass("col-sm-7 col-lg-5").addClass("col-sm-6 col-lg-3");
|
|
} else {
|
|
$(".div-head-temp").addClass("hidden-sm");
|
|
$("#col_extr_totals, #td_extr_total").removeClass("hidden");
|
|
for(var i=1; i<=3; i++) {
|
|
$("th.extr-" + i).html(T("D" + i));
|
|
$("#row_status_2 .extr-" + i).addClass("hidden-md");
|
|
}
|
|
$("#div_heaters").removeClass("col-sm-6").addClass("col-sm-5");
|
|
$("#div_temp_chart").removeClass("col-lg-5").addClass("col-lg-3");
|
|
$("#div_status").removeClass("col-sm-6 col-lg-3").addClass("col-sm-7 col-lg-5");
|
|
}
|
|
|
|
// Charts
|
|
|
|
resizeCharts();
|
|
drawTemperatureChart();
|
|
drawPrintChart();
|
|
}
|
|
|
|
function resetGui() {
|
|
// Charts
|
|
drawTemperatureChart();
|
|
drawPrintChart();
|
|
|
|
// Navbar
|
|
setTitle("Duet Web Control");
|
|
setStatusLabel("Disconnected", "default");
|
|
|
|
// Heater Temperatures
|
|
$("#table_heaters tr > th:first-child > span").text("");
|
|
setCurrentTemperature("bed", undefined);
|
|
setTemperatureInput("bed", 0, 1);
|
|
setCurrentTemperature("chamber", undefined);
|
|
setTemperatureInput("chamber", 0, 1);
|
|
for(var i=1; i<=6; i++) {
|
|
setCurrentTemperature(i, undefined);
|
|
setTemperatureInput(i, 0, 1);
|
|
setTemperatureInput(i, 0, 0);
|
|
}
|
|
|
|
// Status fields
|
|
$("#td_x, #td_y, #td_z").text("n/a");
|
|
for(var i=1; i<=numExtruderDrives; i++) {
|
|
$("#td_extr_" + i).text("n/a");
|
|
}
|
|
$("#td_extr_total").text("n/a");
|
|
setProbeValue(-1, undefined);
|
|
$("#td_fanrpm").text("n/a");
|
|
|
|
// Control page
|
|
setAxesHomed([1,1,1]);
|
|
setATXPower(false);
|
|
$('#slider_fan_control').slider("setValue", 35);
|
|
|
|
// Print Status
|
|
$(".row-progress").addClass("hidden");
|
|
setProgress(100, "", "");
|
|
$("#override_fan, #auto_sleep").prop("checked", false);
|
|
$('#slider_fan_print').slider("setValue", 35);
|
|
$("#page_print dd, #panel_print_info table td, #table_estimations td").html("n/a");
|
|
$('#slider_speed').slider("setValue", 100);
|
|
for(var extr=1; extr<=6; extr++) {
|
|
$("#slider_extr_" + extr).slider("setValue", 100);
|
|
}
|
|
|
|
// G-Code Console is not cleared automatically
|
|
|
|
// G-Code Files
|
|
updateGCodeFiles();
|
|
|
|
// Macro Files
|
|
updateMacroFiles();
|
|
|
|
// Settings
|
|
$("#firmware_name, #firmware_version").html("n/a");
|
|
$("#page_machine td:not(:first-child), #page_machine dd").html("n/a");
|
|
$("#div_config > h1").removeClass("hidden");
|
|
$("#text_config").addClass("hidden");
|
|
|
|
// Modal dialogs
|
|
$("#modal_upload").modal("hide");
|
|
}
|
|
|
|
function updateWebcam(externalTrigger) {
|
|
if (externalTrigger && webcamUpdating) {
|
|
// When the settings are applied, make sure this only runs once
|
|
return;
|
|
}
|
|
|
|
if (settings.webcamURL == "") {
|
|
webcamUpdating = false;
|
|
} else {
|
|
var newURL = settings.webcamURL;
|
|
if (newURL.indexOf("?") == -1) {
|
|
newURL += "?dummy=" + Math.random();
|
|
} else {
|
|
newURL += "&dummy=" + Math.random();
|
|
}
|
|
$("#img_webcam").attr("src", newURL);
|
|
|
|
webcamUpdating = true;
|
|
setTimeout(function() {
|
|
updateWebcam(false);
|
|
}, settings.webcamInterval);
|
|
}
|
|
}
|
|
|
|
/* Dynamic GUI Events */
|
|
|
|
$("body").on("click", ".bed-temp", function(e) {
|
|
if ($(this).parents("#tr_bed").length > 0) {
|
|
sendGCode("M140 S" + $(this).data("temp"));
|
|
} else {
|
|
sendGCode("M141 S" + $(this).data("temp"));
|
|
}
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".btn-macro", function(e) {
|
|
var directory = $(this).data("directory");
|
|
if (directory != undefined) {
|
|
var dropdown = $(this).parent().children("ul");
|
|
dropdown.css("width", $(this).outerWidth());
|
|
loadMacroDropdown(directory, dropdown);
|
|
dropdown.dropdown();
|
|
} else {
|
|
sendGCode("M98 P" + $(this).data("macro"));
|
|
}
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".btn-print-file, .gcode-file", function(e) {
|
|
var file = $(this).parents("tr").data("file");
|
|
showConfirmationDialog(T("Start Print"), T("Do you want to print <strong>{0}</strong>?", file), function() {
|
|
waitingForPrintStart = true;
|
|
if (currentGCodeDirectory == "/gcodes") {
|
|
sendGCode("M32 " + file);
|
|
} else {
|
|
sendGCode("M32 " + currentGCodeDirectory.substring(8) + "/" + file);
|
|
}
|
|
});
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".btn-delete-file", function(e) {
|
|
var row = $(this).parents("tr");
|
|
var file = row.data("file");
|
|
showConfirmationDialog(T("Delete File"), T("Are you sure you want to delete <strong>{0}</strong>?", file), function() {
|
|
$.ajax("rr_delete?name=" + encodeURIComponent(currentGCodeDirectory + "/" + file), {
|
|
dataType: "json",
|
|
row: row,
|
|
file: file,
|
|
success: function(response) {
|
|
if (response.err == 0) {
|
|
this.row.remove();
|
|
if ($("#table_gcode_files tbody").children().length == 0) {
|
|
gcodeUpdateIndex = -1;
|
|
updateGCodeFiles();
|
|
}
|
|
} else {
|
|
showMessage("warning-sign", T("Deletion failed"), T("<strong>Warning:</strong> Could not delete file <strong>{0}</strong>!", this.file), "md");
|
|
}
|
|
}
|
|
});
|
|
});
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".btn-delete-gcode-directory", function(e) {
|
|
var row = $(this).parents("tr");
|
|
var directory = row.data("directory");
|
|
$.ajax("rr_delete?name=" + encodeURIComponent(currentGCodeDirectory + "/" + directory), {
|
|
dataType: "json",
|
|
row: row,
|
|
directory: directory,
|
|
success: function(response) {
|
|
if (response.err == 0) {
|
|
this.row.remove();
|
|
if ($("#table_gcode_files tbody").children().length == 0) {
|
|
gcodeUpdateIndex = -1;
|
|
updateGCodeFiles();
|
|
}
|
|
} else {
|
|
showMessage("warning-sign", T("Deletion failed"), T("<strong>Warning:</strong> Could not delete directory <strong>{0}</strong>!<br/><br/>Perhaps it isn't empty?", this.directory), "md");
|
|
}
|
|
}
|
|
});
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".btn-delete-parent", function(e) {
|
|
$(this).parents("tr, li").remove();
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".btn-delete-macro-directory", function(e) {
|
|
var row = $(this).parents("tr");
|
|
var directory = row.data("directory");
|
|
$.ajax("rr_delete?name=" + encodeURIComponent(currentMacroDirectory + "/" + directory), {
|
|
dataType: "json",
|
|
row: row,
|
|
directory: directory,
|
|
success: function(response) {
|
|
if (response.err == 0) {
|
|
if (currentMacroDirectory == "/macros") {
|
|
var button = $("#panel_macro_buttons button[data-macro='" + currentMacroDirectory + "/" + this.directory + "']");
|
|
button.remove();
|
|
}
|
|
this.row.remove();
|
|
if ($("#table_macro_files tbody").children().length == 0) {
|
|
macroUpdateIndex = -1;
|
|
updateMacroFiles();
|
|
}
|
|
} else {
|
|
showMessage("warning-sign", T("Deletion failed"), T("<strong>Warning:</strong> Could not delete directory <strong>{0}</strong>!<br/><br/>Perhaps it isn't empty?", this.directory), "md");
|
|
}
|
|
}
|
|
});
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".btn-delete-macro", function(e) {
|
|
var macroFile = $(this).parents("tr").data("file");
|
|
showConfirmationDialog("Delete File", "Are you sure you want to delete <strong>" + macroFile + "</strong>?", function() {
|
|
$.ajax("rr_delete?name=" + encodeURIComponent(currentMacroDirectory + "/" + macroFile), {
|
|
dataType: "json",
|
|
macro: macroFile,
|
|
success: function(response) {
|
|
if (response.err == 0) {
|
|
$("#table_macro_files tr[data-item='" + macroFile + "'], #panel_macro_buttons button[data-macro='" + currentMacroDirectory + "/" + macroFile + "']").remove();
|
|
if ($("#table_macro_files tbody").children().length == 0) {
|
|
macroUpdateIndex = -1;
|
|
updateMacroFiles();
|
|
}
|
|
} else {
|
|
showMessage("warning-sign", T("Deletion failed"), T("<strong>Warning:</strong> Could not delete macro <strong>{0}</strong>!", this.macro), "md");
|
|
}
|
|
}
|
|
});
|
|
});
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".btn-remove-tool", function(e) {
|
|
var tool = $(this).parents("div.panel-body").data("tool");
|
|
showConfirmationDialog(T("Delete Tool"), T("Are you sure you wish to remove tool {0}?", tool), function() {
|
|
sendGCode("M563 P" + tool + " D-1 H-1");
|
|
extendedStatusCounter = settings.extendedStatusInterval;
|
|
});
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".btn-run-macro", function(e) {
|
|
sendGCode("M98 P" + currentMacroDirectory + "/" + $(this).parents("tr").data("file"));
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".btn-select-tool", function(e) {
|
|
var tool = $(this).parents("div.panel-body").data("tool");
|
|
if (lastStatusResponse != undefined && lastStatusResponse.currentTool == tool) {
|
|
changeTool(-1);
|
|
} else {
|
|
changeTool(tool);
|
|
}
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", "#dropdown_language a", function(e) {
|
|
$("#btn_language > span:first-child").text($(this).text());
|
|
$("#btn_language").data("language", $(this).data("language"));
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".filament-usage", function(e) {
|
|
if (window.matchMedia('(max-width: 991px)').matches) {
|
|
// Display filament usage for small devices on click
|
|
showMessage("info-sign", T("Filament usage"), $(this).attr("title"), "xs");
|
|
}
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".gcode", function(e) {
|
|
if (isConnected) {
|
|
// If this G-Code isn't performed by a button, treat it as a manual input
|
|
sendGCode($(this).data("gcode"), !($(this).is(".btn")));
|
|
}
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".gcode-directory", function(e) {
|
|
setGCodeDirectory(currentGCodeDirectory + "/" + $(this).parents("tr").data("directory"));
|
|
gcodeUpdateIndex = -1;
|
|
updateGCodeFiles();
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".heater-temp", function(e) {
|
|
var inputElement = $(this).parents("div.input-group").find("input");
|
|
var activeOrStandby = (inputElement.prop("id").match("active$")) ? "S" : "R";
|
|
var temperature = $(this).data("temp");
|
|
|
|
if (inputElement.prop("id").indexOf("all") == -1) {
|
|
var heater = inputElement.prop("id").match("_h(.)_")[1];
|
|
getToolsByHeater(heater).forEach(function(tool) {
|
|
sendGCode("G10 P" + tool + " " + activeOrStandby + temperature);
|
|
});
|
|
} else {
|
|
if (toolMapping != undefined) {
|
|
for(var i=0; i<toolMapping.length; i++) {
|
|
var number = (toolMapping[i].hasOwnProperty("number") ? toolMapping[i].number : i + 1);
|
|
if ($.inArray(0, toolMapping[i].heaters) == -1) {
|
|
// Make sure we don't set temperatures for the heated bed
|
|
sendGCode("G10 P" + number + " " + activeOrStandby + $(this).val());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", ".macro-directory", function(e) {
|
|
setMacroDirectory(currentMacroDirectory + "/" + $(this).parents("tr").data("directory"));
|
|
macroUpdateIndex = -1;
|
|
updateMacroFiles();
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", "#ol_gcode_directory a", function(e) {
|
|
setGCodeDirectory($(this).data("directory"));
|
|
gcodeUpdateIndex = -1;
|
|
updateGCodeFiles();
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("click", "#ol_macro_directory a", function(e) {
|
|
setMacroDirectory($(this).data("directory"));
|
|
macroUpdateIndex = -1;
|
|
updateMacroFiles();
|
|
e.preventDefault();
|
|
});
|
|
|
|
var draggingObject;
|
|
|
|
function fileDragStart(e) {
|
|
draggingObject = $(this);
|
|
// The following doesn't work, although it's recommended. I wonder who invented this crappy API...
|
|
//e.dataTransfer.setData('text/html', this.innerHTML);
|
|
}
|
|
|
|
function fileDragEnd(e) {
|
|
draggingObject = undefined;
|
|
}
|
|
|
|
$("#table_gcode_files, #table_macro_files").on("dragover", "tr", function(e) {
|
|
if (draggingObject != undefined && $(e.target).closest("tr").data("directory") != undefined) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
|
|
$("#table_gcode_files, #table_macro_files").on("drop", "tr", function(e) {
|
|
if (draggingObject == undefined) {
|
|
return;
|
|
}
|
|
draggingObject = draggingObject.closest("tr");
|
|
|
|
var targetDir = $(e.target).closest("tr").data("directory");
|
|
if (targetDir != undefined) {
|
|
var sourcePath = draggingObject.data("item");
|
|
var targetPath;
|
|
if (currentPage == "files") {
|
|
targetPath = currentGCodeDirectory + "/" + targetDir + "/" + sourcePath;
|
|
sourcePath = currentGCodeDirectory + "/" + sourcePath;
|
|
} else {
|
|
targetPath = currentMacroDirectory + "/" + targetDir + "/" + sourcePath;
|
|
sourcePath = currentMacroDirectory + "/" + sourcePath;
|
|
}
|
|
|
|
$.ajax("rr_move?old=" + encodeURIComponent(sourcePath) + "&new=" + encodeURIComponent(targetPath), {
|
|
dataType: "json",
|
|
row: draggingObject,
|
|
success: function(response) {
|
|
if (response.err == 0) {
|
|
// We can never run out of files/dirs if we move FSOs to sub-directories...
|
|
this.row.remove();
|
|
}
|
|
}
|
|
});
|
|
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
|
|
$("#ol_gcode_directory, #ol_macro_directory").on("dragover", "a", function(e) {
|
|
if (draggingObject != undefined) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
|
|
$("#ol_gcode_directory, #ol_macro_directory").on("drop", "a", function(e) {
|
|
if (draggingObject == undefined) {
|
|
return;
|
|
}
|
|
draggingObject = draggingObject.closest("tr");
|
|
|
|
var targetDir = $(e.target).data("directory");
|
|
if (targetDir != undefined) {
|
|
var sourcePath = draggingObject.data("item");
|
|
var targetPath, fileTable;
|
|
if (currentPage == "files") {
|
|
targetPath = targetDir + "/" + sourcePath;
|
|
sourcePath = currentGCodeDirectory + "/" + sourcePath;
|
|
fileTable = $("#table_gcode_files > tbody");
|
|
} else {
|
|
targetPath = targetDir + "/" + sourcePath;
|
|
sourcePath = currentMacroDirectory + "/" + sourcePath;
|
|
fileTable = $("#table_macro_files > tbody");
|
|
}
|
|
|
|
$.ajax("rr_move?old=" + encodeURIComponent(sourcePath) + "&new=" + encodeURIComponent(targetPath), {
|
|
dataType: "json",
|
|
row: draggingObject,
|
|
table: fileTable,
|
|
success: function(response) {
|
|
if (response.err == 0) {
|
|
this.row.remove();
|
|
if (this.table.children().length == 0) {
|
|
if (currentPage == "files") {
|
|
gcodeUpdateIndex = -1;
|
|
updateGCodeFiles();
|
|
} else {
|
|
macroUpdateIndex = -1;
|
|
updateMacroFiles();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
|
|
$("body").on("click", ".tool", function(e) {
|
|
changeTool($(this).data("tool"));
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("body").on("hidden.bs.popover", function() {
|
|
$(this).popover("destroy");
|
|
});
|
|
|
|
/* Static GUI Events */
|
|
|
|
$("#a_heaters_off").click(function(e) {
|
|
if (isConnected) {
|
|
// Turn off nozzle heaters
|
|
if (toolMapping != undefined) {
|
|
for(var i=0; i<toolMapping.length; i++) {
|
|
var number = (toolMapping[i].hasOwnProperty("number") ? toolMapping[i].number : i + 1);
|
|
|
|
var temps = [], tempString = "";
|
|
toolMapping[i].heaters.forEach(function() { temps.push("-273.15"); });
|
|
tempString = temps.reduce(function(a, b) { return a + ":" + b; });
|
|
|
|
sendGCode("G10 P" + number + " R" + tempString + " S" + tempString);
|
|
}
|
|
}
|
|
|
|
// Turn off bed
|
|
if (heatedBed) {
|
|
sendGCode("M140 S-273.15");
|
|
}
|
|
|
|
// Turn off chamber
|
|
if (chamber) {
|
|
sendGCode("M141 S-273.15");
|
|
}
|
|
}
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("#a_webcam").click(function(e) {
|
|
if ($("#img_webcam").hasClass("hidden")) {
|
|
$("#span_webcam").removeClass("glyphicon-menu-up").addClass("glyphicon-menu-down");
|
|
$("#img_webcam").removeClass("hidden");
|
|
} else {
|
|
$("#span_webcam").removeClass("glyphicon-menu-down").addClass("glyphicon-menu-up");
|
|
$("#img_webcam").addClass("hidden");
|
|
}
|
|
$(this).blur();
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("#btn_add_gcode").click(function(e) {
|
|
var item = '<tr><td><label class="label label-primary">' + $("#input_gcode").val().trim() + '</label></td><td>' + $("#input_gcode_description").val().trim() + '</td><td>';
|
|
item += '<button class="btn btn-sm btn-danger btn-delete-parent" title="' + T("Delete this G-Code item") + '">';
|
|
item += '<span class="glyphicon glyphicon-trash"></span></button></td></tr>';
|
|
$("#table_gcodes").append(item);
|
|
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("#btn_add_head_temp").click(function(e) {
|
|
var temperature = checkBoundaries($("#input_add_head_temp").val(), 0, -273.15, 300);
|
|
var type = $('input[name="temp_selection"]:checked').val();
|
|
|
|
var item = '<li class="list-group-item col-xs-6 col-lg-3" data-temperature="' + temperature + '">' + temperature + ' °C';
|
|
item += '<button class="btn btn-danger btn-sm btn-delete-parent pull-right" title="' + T("Delete this temperature item") + '">';
|
|
item += '<span class="glyphicon glyphicon-trash"></span></button></li>';
|
|
$("#ul_" + type + "_temps").append(item);
|
|
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("#btn_add_bed_temp").click(function(e) {
|
|
var temperature = checkBoundaries($("#input_add_bed_temp").val(), 0, -273.15, 180);
|
|
|
|
var item = '<li class="list-group-item col-md-6" data-temperature="' + temperature + '">' + temperature + ' °C';
|
|
item += '<button class="btn btn-danger btn-sm btn-delete-parent pull-right" title="' + T("Delete this temperature item") + '">';
|
|
item += '<span class="glyphicon glyphicon-trash"></span></button></li>';
|
|
$("#ul_bed_temps").append(item);
|
|
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("#btn_add_tool").click(function(e) {
|
|
var gcode = "M563 P" + $("#input_tool_number").val();
|
|
|
|
var drives = $("input[name='tool_drives']:checked");
|
|
if (drives != undefined) {
|
|
var driveList = [];
|
|
drives.each(function() { driveList.push($(this).val()); });
|
|
gcode += " D" + driveList.reduce(function(a, b) { return a + ":" + b; });
|
|
}
|
|
|
|
var heaters = $("input[name='tool_heaters']:checked");
|
|
if (heaters != undefined) {
|
|
var heaterList = [];
|
|
heaters.each(function() { heaterList.push($(this).val()); });
|
|
gcode += " H" + heaterList.reduce(function(a, b) { return a + ":" + b; });
|
|
}
|
|
|
|
sendGCode(gcode);
|
|
extendedStatusCounter = settings.extendedStatusInterval;
|
|
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("#btn_cancel").click(function() {
|
|
sendGCode("M0 H1"); // Stop / Cancel Print, but leave all the heaters on
|
|
$(this).addClass("disabled");
|
|
});
|
|
|
|
$("#btn_cancel_upload").click(function() {
|
|
cancelUpload();
|
|
});
|
|
|
|
$(".btn-connect").click(function() {
|
|
if (!isConnected) {
|
|
// Attempt to connect with the last-known password first
|
|
connect(sessionPassword, true);
|
|
} else {
|
|
disconnect();
|
|
}
|
|
});
|
|
|
|
$(".btn-emergency-stop").click(function() {
|
|
if (settings.confirmStop) {
|
|
showConfirmationDialog(T("Emergency STOP"), T("This will turn off everything and perform a software reset.<br/><br/>Are you REALLY sure you want to do this?"), function() {
|
|
sendGCode("M112\nM999");
|
|
});
|
|
} else {
|
|
sendGCode("M112\nM999");
|
|
}
|
|
});
|
|
|
|
$("#btn_fw_diagnostics").click(function() {
|
|
if (isConnected) {
|
|
sendGCode("M122");
|
|
showPage("console");
|
|
}
|
|
});
|
|
|
|
$("#btn_clear_log").click(function(e) {
|
|
$("#console_log").html("");
|
|
log("info", "<strong>" + T("Message Log cleared!") + "</strong>");
|
|
e.preventDefault();
|
|
});
|
|
|
|
// TODO: deal with mixing drives
|
|
$("#btn_extrude").click(function(e) {
|
|
var feedrate = $("#panel_extrude input[name=feedrate]:checked").val() * 60;
|
|
var amount = $("#panel_extrude input[name=feed]:checked").val();
|
|
sendGCode("M120\nM83\nG1 E" + amount + " F" + feedrate + "\nM121");
|
|
});
|
|
$("#btn_retract").click(function(e) {
|
|
var feedrate = $("#panel_extrude input[name=feedrate]:checked").val() * 60;
|
|
var amount = $("#panel_extrude input[name=feed]:checked").val();
|
|
sendGCode("M120\nM83\nG1 E-" + amount + " F" + feedrate + "\nM121");
|
|
});
|
|
|
|
$(".btn-hide-info").click(function() {
|
|
if ($(this).hasClass("active")) {
|
|
$("#row_info").addClass("hidden-xs hidden-sm");
|
|
$("#main_content").addClass("content-collapsed-padding");
|
|
setTimeout(function() {
|
|
$(".btn-hide-info").removeClass("active");
|
|
}, 100);
|
|
} else {
|
|
$("#row_info").removeClass("hidden-xs hidden-sm");
|
|
$("#main_content").removeClass("content-collapsed-padding");
|
|
setTimeout(function() {
|
|
$(".btn-hide-info").addClass("active");
|
|
}, 100);
|
|
}
|
|
$(this).blur();
|
|
});
|
|
|
|
$(".btn-home-x").resize(function() {
|
|
if (geometry != "delta") {
|
|
var width = $(this).parent().width();
|
|
if (width > 0) {
|
|
$("#btn_homeall").css("min-width", width);
|
|
}
|
|
}
|
|
}).resize();
|
|
|
|
$("#mobile_home_buttons button, #btn_homeall, #table_move_head a").click(function(e) {
|
|
$this = $(this);
|
|
if ($this.data("home") != undefined) {
|
|
if ($this.data("home") == "all") {
|
|
sendGCode("G28");
|
|
} else {
|
|
sendGCode("G28 " + $this.data("home"));
|
|
}
|
|
} else {
|
|
var moveString = "M120\nG91\nG1";
|
|
if ($this.data("x") != undefined) {
|
|
moveString += " X" + $this.data("x");
|
|
}
|
|
if ($this.data("y") != undefined) {
|
|
moveString += " Y" + $this.data("y");
|
|
}
|
|
if ($this.data("z") != undefined) {
|
|
moveString += " Z" + $this.data("z");
|
|
}
|
|
moveString += " F" + settings.moveFeedrate + "\nM121";
|
|
sendGCode(moveString);
|
|
}
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("#btn_new_gcode_directory").click(function() {
|
|
showTextInput(T("New directory"), T("Please enter a name:"), function(value) {
|
|
$.ajax("rr_mkdir?dir=" + currentGCodeDirectory + "/" + value, {
|
|
dataType: "json",
|
|
success: function(response) {
|
|
if (response.err == 0) {
|
|
gcodeUpdateIndex = -1;
|
|
updateGCodeFiles();
|
|
} else {
|
|
showMessage("warning-sign", T("Error"), T("Could not create this directory!"), "sm");
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
$("#btn_new_macro_directory").click(function() {
|
|
showTextInput(T("New directory"), T("Please enter a name:"), function(value) {
|
|
$.ajax("rr_mkdir?dir=" + currentMacroDirectory + "/" + value, {
|
|
dataType: "json",
|
|
success: function(response) {
|
|
if (response.err == 0) {
|
|
macroUpdateIndex = -1;
|
|
updateMacroFiles();
|
|
} else {
|
|
showMessage("warning-sign", T("Error"), T("Could not create this directory!"), "sm");
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
$("#btn_pause").click(function() {
|
|
if (isPaused) {
|
|
sendGCode("M24"); // Resume
|
|
} else if (isPrinting) {
|
|
sendGCode("M25"); // Pause
|
|
}
|
|
$(this).addClass("disabled");
|
|
});
|
|
|
|
$(".btn-upload").click(function(e) {
|
|
$("#input_file_upload").data("type", $(this).data("type")).click();
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("#btn_reset_settings").click(function(e) {
|
|
showConfirmationDialog(T("Reset Settings"), T("Are you sure you want to revert to Factory Settings?"), function() {
|
|
if (defaultSettings.language != settings.language) {
|
|
showMessage("info-sign", T("Language has changed"), T("You have changed the current language.<br/><br/>Please reload the web interface to apply this change."), "md");
|
|
}
|
|
settings = jQuery.extend(true, {}, defaultSettings);
|
|
$("#btn_language").data("language", "en").children("span:first-child").text("English");
|
|
applySettings();
|
|
saveSettings();
|
|
});
|
|
e.preventDefault();
|
|
});
|
|
|
|
["print", "gcode", "macro", "generic"].forEach(function(type) {
|
|
var child = $(".btn-upload[data-type='" + type + "']");
|
|
|
|
// Drag Enter
|
|
child.on("dragover", function(e) {
|
|
$(this).removeClass($(this).data("style")).addClass("btn-success");
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
});
|
|
|
|
// Drag Leave
|
|
child.on("dragleave", function(e) {
|
|
$(this).removeClass("btn-success").addClass($(this).data("style"));
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
});
|
|
|
|
// Drop
|
|
child.on("drop", function(e) {
|
|
$(this).removeClass("btn-success").addClass($(this).data("style"));
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
var files = e.originalEvent.dataTransfer.files;
|
|
if (files != null && files.length > 0) {
|
|
// Start new file upload
|
|
startUpload($(this).data("type"), files, false);
|
|
}
|
|
});
|
|
});
|
|
|
|
$(".gcode-input").submit(function(e) {
|
|
if (isConnected) {
|
|
var gcode = $(this).find("input").val();
|
|
if (settings.uppercaseGCode) {
|
|
gcode = gcode.toUpperCase();
|
|
}
|
|
sendGCode(gcode, true);
|
|
$(this).find("input").select();
|
|
}
|
|
e.preventDefault();
|
|
});
|
|
|
|
// Make the auto-complete dropdown items look proper.
|
|
// This should be replaced by proper CSS someday, but
|
|
// for now we only check which elements may float around.
|
|
$(".div-gcodes").bind("shown.bs.dropdown", function() {
|
|
var maxWidth = 0;
|
|
$(this).find("ul > li > a").each(function() {
|
|
var rowWidth = 0;
|
|
$(this).find("span").each(function() {
|
|
rowWidth += $(this).width();
|
|
});
|
|
|
|
if (rowWidth > maxWidth) {
|
|
maxWidth = rowWidth;
|
|
}
|
|
});
|
|
|
|
if (maxWidth > 0) {
|
|
$(this).find("ul > li > a").each(function() {
|
|
var rowWidth = 0;
|
|
$(this).find("span").each(function() {
|
|
rowWidth += $(this).width();
|
|
});
|
|
|
|
if (rowWidth < maxWidth) {
|
|
$(this).addClass("gcode-float");
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
$("#frm_settings").submit(function(e) {
|
|
saveSettings();
|
|
applySettings();
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("#frm_settings > ul > li a").on("shown.bs.tab", function(e) {
|
|
$("#frm_settings > ul li").removeClass("active");
|
|
var links = $('#frm_settings > ul > li a[href="' + $(this).attr("href") + '"]');
|
|
$.each(links, function() {
|
|
$(this).parent().addClass("active");
|
|
});
|
|
});
|
|
|
|
$("input[type='number']").focus(function() {
|
|
var input = $(this);
|
|
setTimeout(function() {
|
|
input.select();
|
|
}, 10);
|
|
});
|
|
|
|
$("input[name='temp_selection']:radio").change(function() {
|
|
if ($(this).val() == "active") {
|
|
$("#ul_active_temps").removeClass("hidden");
|
|
$("#ul_standby_temps").addClass("hidden");
|
|
} else {
|
|
$("#ul_standby_temps").removeClass("hidden");
|
|
$("#ul_active_temps").addClass("hidden");
|
|
}
|
|
});
|
|
|
|
$("#input_file_upload").change(function(e) {
|
|
if (this.files.length > 0) {
|
|
// For POST uploads, we need file blobs
|
|
startUpload($(this).data("type"), this.files, false);
|
|
}
|
|
});
|
|
|
|
$("#input_temp_bed").keydown(function(e) {
|
|
var enterKeyPressed = (e.which == 13);
|
|
enterKeyPressed |= (e.which == 9 && window.matchMedia('(max-width: 991px)').matches); // need this for Android
|
|
if (isConnected && enterKeyPressed) {
|
|
sendGCode("M140 S" + $(this).val());
|
|
$(this).select();
|
|
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
|
|
$("#input_temp_chamber").keydown(function(e) {
|
|
var enterKeyPressed = (e.which == 13);
|
|
enterKeyPressed |= (e.which == 9 && window.matchMedia('(max-width: 991px)').matches); // need this for Android
|
|
if (isConnected && enterKeyPressed) {
|
|
sendGCode("M141 S" + $(this).val());
|
|
$(this).select();
|
|
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
|
|
$("input[id^='input_temp_h']").keydown(function(e) {
|
|
var enterKeyPressed = (e.which == 13);
|
|
enterKeyPressed |= (e.which == 9 && window.matchMedia('(max-width: 991px)').matches); // need this for Android
|
|
if (isConnected && enterKeyPressed) {
|
|
var activeOrStandby = ($(this).prop("id").match("active$")) ? "S" : "R";
|
|
var heater = $(this).prop("id").match("_h(.)_")[1];
|
|
var temperature = $(this).val();
|
|
|
|
getToolsByHeater(heater).forEach(function(toolNumber) {
|
|
sendGCode("G10 P" + toolNumber + " " + activeOrStandby + temperature);
|
|
});
|
|
$(this).select();
|
|
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
|
|
$("#input_temp_all_active, #input_temp_all_standby").keydown(function(e) {
|
|
if (isConnected && e.which == 13) {
|
|
if (toolMapping != undefined) {
|
|
var activeOrStandby = ($(this).prop("id").match("active$")) ? "S" : "R";
|
|
var temperature = $(this).val();
|
|
|
|
for(var i=0; i<toolMapping.length; i++) {
|
|
var number = (toolMapping[i].hasOwnProperty("number") ? toolMapping[i].number : i + 1);
|
|
if ($.inArray(0, toolMapping[i].heaters) == -1) {
|
|
// Make sure we don't set temperatures for the heated bed
|
|
sendGCode("G10 P" + number + " " + activeOrStandby + $(this).val());
|
|
}
|
|
}
|
|
}
|
|
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
|
|
$(".navbar-brand").click(function(e) { e.preventDefault(); });
|
|
$(".navbar-brand.visible-xs > abbr").click(function(e) {
|
|
showMessage("warning-sign", T("Warning"), T("Some axes are not homed"), "sm");
|
|
e.preventDefault();
|
|
});
|
|
|
|
$(".navlink").click(function(e) {
|
|
$(this).blur();
|
|
showPage($(this).data("target"));
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("#page_listitems input").on("input", function() {
|
|
// Validate form controls
|
|
$("#btn_add_gcode").toggleClass("disabled", $("#input_gcode").val().trim() == "" || $("#input_gcode_description").val().trim() == "");
|
|
$("#btn_add_head_temp").toggleClass("disabled", isNaN(parseFloat($("#input_add_head_temp").val())));
|
|
$("#btn_add_bed_temp").toggleClass("disabled", isNaN(parseFloat($("#input_add_bed_temp").val())));
|
|
});
|
|
|
|
$("#page_listitems input").keydown(function(e) {
|
|
if (e.which == 13) {
|
|
var button = $(this).parents("div:not(.input-group):eq(0)").find("button");
|
|
if (!button.hasClass("disabled")) {
|
|
button.click();
|
|
}
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
|
|
$("#panel_control_misc label.btn").click(function() {
|
|
if ($(this).find("input").val() == 1) { // ATX on
|
|
sendGCode("M80");
|
|
} else { // ATX off
|
|
showConfirmationDialog(T("ATX Power"), T("Do you really want to turn off ATX power?<br/><br/>This will turn off all drives, heaters and fans."), function() {
|
|
sendGCode("M81");
|
|
});
|
|
}
|
|
});
|
|
|
|
$("#panel_extrude label.btn").click(function() {
|
|
$(this).parent().find("label.btn").removeClass("btn-primary").addClass("btn-default");
|
|
$(this).removeClass("btn-default").addClass("btn-primary");
|
|
});
|
|
|
|
$(".span-refresh-files").click(function() {
|
|
gcodeUpdateIndex = -1;
|
|
updateGCodeFiles();
|
|
$(".span-refresh-files").addClass("hidden");
|
|
});
|
|
|
|
$(".span-refresh-macros").click(function() {
|
|
macroUpdateIndex = -1;
|
|
updateMacroFiles();
|
|
$(".span-refresh-macros").addClass("hidden");
|
|
});
|
|
|
|
$(document).delegate('#text_config', 'keydown', function(e) {
|
|
var keyCode = e.keyCode || e.which;
|
|
|
|
if (keyCode == 9) {
|
|
e.preventDefault();
|
|
var start = $(this).get(0).selectionStart;
|
|
var end = $(this).get(0).selectionEnd;
|
|
|
|
// set textarea value to: text before caret + tab + text after caret
|
|
$(this).val($(this).val().substring(0, start)
|
|
+ "\t"
|
|
+ $(this).val().substring(end));
|
|
|
|
// put caret at right position again
|
|
$(this).get(0).selectionStart = $(this).get(0).selectionEnd = start + 1;
|
|
}
|
|
});
|
|
|
|
$(".panel-chart").resize(function() {
|
|
resizeCharts();
|
|
});
|
|
|
|
$('a[href="#page_general"], a[href="#page_listitems"]').on('shown.bs.tab', function () {
|
|
$("#row_save_settings, #btn_reset_settings").removeClass("hidden");
|
|
});
|
|
|
|
$('a[href="#page_config"]').on('shown.bs.tab', function() {
|
|
$("#row_save_settings, #btn_reset_settings").addClass("hidden");
|
|
$("#text_config").trigger("input");
|
|
getConfigFile();
|
|
});
|
|
|
|
$('a[href="#page_machine"], a[href="#page_tools"]').on('shown.bs.tab', function () {
|
|
$("#row_save_settings").addClass("hidden");
|
|
});
|
|
|
|
$("#table_heaters a").click(function(e) {
|
|
if (isConnected && lastStatusResponse != undefined) {
|
|
if ($(this).parents("#tr_bed").length > 0) {
|
|
var bedState = lastStatusResponse.temps.bed.state;
|
|
if (bedState == 3) {
|
|
showMessage("exclamation-sign", T("Heater Fault"), T("<strong>Error:</strong> A heater fault has occured on this particular heater.<br/><br/>Please turn off your machine and check your wiring for loose connections."), "md");
|
|
} else if (bedState == 2) {
|
|
// Put bed into standby mode
|
|
sendGCode("M144");
|
|
} else {
|
|
// Bed is either off or in standby mode, send M140 to turn it back on
|
|
sendGCode("M140 S" + $("#input_temp_bed").val());
|
|
}
|
|
} else {
|
|
var heater = $(this).parents("tr").index();
|
|
var heaterState = lastStatusResponse.temps.heads.state[heater - 1];
|
|
if (heaterState == 3) {
|
|
showMessage("exclamation-sign", T("Heater Fault"), T("<strong>Error:</strong> A heater fault has occured on this particular heater.<br/><br/>Please turn off your machine and check your wiring for loose connections."), "md");
|
|
} else {
|
|
var tools = getToolsByHeater(heater), hasToolSelected = false;
|
|
tools.forEach(function(tool) {
|
|
if (tool == lastStatusResponse.currentTool) {
|
|
hasToolSelected = true;
|
|
}
|
|
});
|
|
|
|
if (hasToolSelected) {
|
|
changeTool(-1);
|
|
$(this).blur();
|
|
} else if (tools.length == 1) {
|
|
changeTool(tools[0]);
|
|
$(this).blur();
|
|
} else if (tools.length > 0) {
|
|
var popover = $(this).parent().children("div.popover");
|
|
if (popover.length) {
|
|
$(this).popover("hide");
|
|
$(this).blur();
|
|
} else {
|
|
var content = '<div class="btn-group-vertical btn-group-vertical-justified">';
|
|
tools.forEach(function(toolNumber) {
|
|
content += '<div class="btn-group"><a href="#" class="btn btn-default btn-sm tool" data-tool="' + toolNumber + '">T' + toolNumber + '</a></div>';
|
|
});
|
|
content += '</div>';
|
|
|
|
$(this).popover({
|
|
content: content,
|
|
html: true,
|
|
title: T("Select Tool"),
|
|
trigger: "manual",
|
|
placement: "bottom",
|
|
}).popover("show");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
e.preventDefault();
|
|
});
|
|
|
|
$("#table_define_tool input[type='checkbox']").change(function() {
|
|
var isChecked = $(this).is(":checked");
|
|
$(this).parents("label").toggleClass("btn-primary", isChecked).toggleClass("btn-default", !isChecked);
|
|
|
|
validateAddTool();
|
|
});
|
|
|
|
$("#table_define_tool input[type='number']").on("input", function() {
|
|
validateAddTool();
|
|
});
|
|
|
|
function validateAddTool() {
|
|
var toolNumber = parseInt($("#input_tool_number").val());
|
|
var disableButton = (!isConnected) ||
|
|
(isNaN(toolNumber) || toolNumber < 0 || toolNumber > 255) ||
|
|
(toolMapping != undefined && getTool(toolNumber) != undefined) ||
|
|
($("input[name='tool_heaters']:checked").length + $("input[name='tool_drives']:checked").length == 0);
|
|
$("#btn_add_tool").toggleClass("disabled", disableButton);
|
|
}
|
|
|
|
$("#table_define_tool input[type='number']").keydown(function(e) {
|
|
if (e.which == 13) {
|
|
if (!$("#btn_add_tool").hasClass("disabled")) {
|
|
$("#btn_add_tool").click();
|
|
}
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
|
|
$("#table_heaters tr > th:first-child > a").blur(function() {
|
|
$(this).popover("hide");
|
|
});
|
|
|
|
$("#ul_control_dropdown").click(function(e) {
|
|
$(this).find(".dropdown").removeClass("open");
|
|
if ($(e.target).is("a")) {
|
|
$(this).parents(".dropdown").removeClass("open");
|
|
} else {
|
|
e.stopPropagation();
|
|
}
|
|
});
|
|
|
|
$("#ul_control_dropdown .btn-active-temp, #ul_control_dropdown .btn-standby-temp").click(function(e) {
|
|
$(this).parent().toggleClass("open");
|
|
e.stopPropagation();
|
|
});
|
|
|
|
/* Temperature charts */
|
|
|
|
function addLayerData(lastLayerTime, updateGui) {
|
|
layerData.push([layerData.length + 1, lastLayerTime]);
|
|
if (lastLayerTime > maxLayerTime) {
|
|
maxLayerTime = lastLayerTime;
|
|
}
|
|
|
|
if (updateGui) {
|
|
$("#td_last_layertime").html(convertSeconds(lastLayerTime)).addClass("layer-done-animation");
|
|
setTimeout(function() {
|
|
$("#td_last_layertime").removeClass("layer-done-animation");
|
|
}, 2000);
|
|
|
|
drawPrintChart();
|
|
}
|
|
}
|
|
|
|
function drawTemperatureChart()
|
|
{
|
|
// Only draw the chart if it's possible
|
|
if ($("#chart_temp").width() === 0) {
|
|
refreshTempChart = true;
|
|
return;
|
|
}
|
|
|
|
// Prepare the data
|
|
var preparedBedTemps = [];
|
|
for(var i=0; i<recordedBedTemperatures.length; i++) {
|
|
preparedBedTemps.push([i, recordedBedTemperatures[i]]);
|
|
}
|
|
var preparedChamberTemps = [];
|
|
for(var i=0; i<recordedChamberTemperatures.length; i++) {
|
|
preparedChamberTemps.push([i, recordedChamberTemperatures[i]]);
|
|
}
|
|
var preparedHeadTemps = [[], [], [], [], [], []], heaterSamples;
|
|
for(var head=0; head<recordedHeadTemperatures.length; head++) {
|
|
heaterSamples = recordedHeadTemperatures[head];
|
|
for(var k=0; k<heaterSamples.length; k++) {
|
|
preparedHeadTemps[head].push([k, heaterSamples[k]]);
|
|
}
|
|
}
|
|
|
|
// Draw it
|
|
if (tempChart == undefined) {
|
|
tempChart = $.plot("#chart_temp", [preparedBedTemps, preparedHeadTemps[0], preparedHeadTemps[1], preparedHeadTemps[2], preparedHeadTemps[3], preparedHeadTemps[4], preparedHeadTemps[5], preparedChamberTemps], tempChartOptions);
|
|
} else {
|
|
tempChart.setData([preparedBedTemps, preparedHeadTemps[0], preparedHeadTemps[1], preparedHeadTemps[2], preparedHeadTemps[3], preparedHeadTemps[4], preparedHeadTemps[5], preparedChamberTemps]);
|
|
tempChart.setupGrid();
|
|
tempChart.draw();
|
|
}
|
|
|
|
refreshTempChart = false;
|
|
}
|
|
|
|
function drawPrintChart() {
|
|
// Only draw the chart if it's possible
|
|
if ($("#chart_print").width() === 0) {
|
|
refreshPrintChart = true;
|
|
return;
|
|
}
|
|
|
|
// Find absolute maximum values for the X axis
|
|
var maxX = 25, maxPanX = 25;
|
|
if (layerData.length < 21) {
|
|
maxX = maxPanX = 20;
|
|
} else if (layerData.length < 25) {
|
|
maxX = maxPanX = layerData.length;
|
|
} else {
|
|
maxPanX = layerData.length;
|
|
}
|
|
printChartOptions.xaxis.max = maxX;
|
|
printChartOptions.xaxis.panRange = [1, maxPanX];
|
|
printChartOptions.xaxis.zoomRange = [25, maxPanX];
|
|
|
|
// Find max visible value for Y axis
|
|
var maxY = 30;
|
|
if (layerData.length > 2) {
|
|
for(var i=(layerData.length > 26) ? layerData.length - 25 : 1; i < layerData.length; i++) {
|
|
if (maxY < layerData[i][1] * 1.1) {
|
|
maxY = layerData[i][1] * 1.1;
|
|
}
|
|
}
|
|
} else if (layerData.length > 0) {
|
|
maxY = layerData[0][1] * 1.1;
|
|
}
|
|
printChartOptions.yaxis.max = maxY;
|
|
printChartOptions.yaxis.panRange = [0, (maxLayerTime < maxY) ? maxY : maxLayerTime];
|
|
printChartOptions.yaxis.zoomRange = [30, (maxLayerTime < maxY) ? maxY : maxLayerTime];
|
|
|
|
// Update chart and pan to the right
|
|
printChart = $.plot("#chart_print", [layerData], printChartOptions);
|
|
printChart.pan({ left: 99999 });
|
|
refreshPrintChart = false;
|
|
|
|
// Add hover events to chart
|
|
$("#chart_print").unbind("plothover").bind("plothover", function (event, pos, item) {
|
|
if (item) {
|
|
var layer = item.datapoint[0];
|
|
if (layer == 0) {
|
|
layer = 1;
|
|
}
|
|
|
|
$("#layer_tooltip").html(T("Layer {0}: {1}", layer, convertSeconds(item.datapoint[1])))
|
|
.css({top: item.pageY + 5, left: item.pageX + 5})
|
|
.fadeIn(200);
|
|
} else {
|
|
$("#layer_tooltip").hide();
|
|
}
|
|
});
|
|
}
|
|
|
|
function resizeCharts() {
|
|
var headsHeight = $("#table_heaters").height();
|
|
var statusHeight = 0;
|
|
$("#div_status table").each(function() {
|
|
statusHeight += $(this).outerHeight();
|
|
});
|
|
|
|
var max = (headsHeight > statusHeight) ? headsHeight : statusHeight;
|
|
max -= tempChartPadding;
|
|
|
|
if (max > 0) {
|
|
$("#chart_temp").css("height", max);
|
|
}
|
|
|
|
if (refreshTempChart) {
|
|
drawTemperatureChart();
|
|
}
|
|
if (refreshPrintChart) {
|
|
drawPrintChart();
|
|
}
|
|
}
|
|
|
|
/* Sliders */
|
|
|
|
$('#slider_fan_control').slider({
|
|
enabled: false,
|
|
id: "fan_control",
|
|
min: 0,
|
|
max: 100,
|
|
step: 1,
|
|
value: 35,
|
|
tooltip: "always",
|
|
|
|
formatter: function(value) {
|
|
return value + " %";
|
|
}
|
|
}).on("slideStart", function() {
|
|
fanSliderActive = true;
|
|
}).on("slideStop", function(slideEvt) {
|
|
if (isConnected && !isNaN(slideEvt.value)) {
|
|
sendGCode("M106 S" + (slideEvt.value / 100.0));
|
|
$("#slider_fan_print").slider("setValue", slideEvt.value);
|
|
}
|
|
fanSliderActive = false;
|
|
});
|
|
|
|
$('#slider_fan_print').slider({
|
|
enabled: false,
|
|
id: "fan_print",
|
|
min: 0,
|
|
max: 100,
|
|
step: 1,
|
|
value: 35,
|
|
tooltip: "always",
|
|
|
|
formatter: function(value) {
|
|
return value + " %";
|
|
}
|
|
}).on("slideStart", function() {
|
|
fanSliderActive = true;
|
|
}).on("slideStop", function(slideEvt) {
|
|
if (isConnected && !isNaN(slideEvt.value)) {
|
|
sendGCode("M106 S" + (slideEvt.value / 100.0));
|
|
$("#slider_fan_control").slider("setValue", slideEvt.value);
|
|
}
|
|
fanSliderActive = false;
|
|
});
|
|
|
|
for(var extr=1; extr<=6; extr++) {
|
|
$('#slider_extr_' + extr).slider({
|
|
enabled: false,
|
|
id: "extr-" + extr,
|
|
min: 50,
|
|
max: 150,
|
|
step: 1,
|
|
value: 100,
|
|
tooltip: "always",
|
|
|
|
formatter: function(value) {
|
|
return value + " %";
|
|
}
|
|
}).on("slideStart", function() {
|
|
extrSliderActive = true;
|
|
}).on("slideStop", function(slideEvt) {
|
|
if (isConnected && !isNaN(slideEvt.value)) {
|
|
sendGCode("M221 D" + $(this).data("drive") + " S" + slideEvt.value);
|
|
}
|
|
extrSliderActive = false;
|
|
});
|
|
}
|
|
|
|
$('#slider_speed').slider({
|
|
enabled: false,
|
|
id: "speed",
|
|
min: 20,
|
|
max: 200,
|
|
step: 1,
|
|
value: 100,
|
|
tooltip: "always",
|
|
|
|
formatter: function(value) {
|
|
return value + " %";
|
|
}
|
|
}).on("slideStart", function() {
|
|
speedSliderActive = true;
|
|
}).on("slideStop", function(slideEvt) {
|
|
if (isConnected && !isNaN(slideEvt.value)) {
|
|
sendGCode("M220 S" + slideEvt.value);
|
|
}
|
|
speedSliderActive = false;
|
|
});
|
|
|
|
/* Modals */
|
|
|
|
function showConfirmationDialog(title, message, action) {
|
|
$("#modal_confirmation h4").html('<span class="glyphicon glyphicon-question-sign"></span> ' + title);
|
|
$("#modal_confirmation p").html(message);
|
|
$("#modal_confirmation button:first-child").off().one("click", action);
|
|
$("#modal_confirmation").modal("show");
|
|
$("#modal_confirmation .btn-success").focus();
|
|
}
|
|
|
|
function showTextInput(title, message, action) {
|
|
$("#modal_textinput h4").html(title);
|
|
$("#modal_textinput p").html(message);
|
|
$("#modal_textinput input").val("");
|
|
$("#modal_textinput form").off().submit(function(e) {
|
|
$("#modal_textinput").modal("hide");
|
|
var value = $("#modal_textinput input").val();
|
|
if (value.trim() != "") {
|
|
action(value);
|
|
}
|
|
e.preventDefault();
|
|
});
|
|
$("#modal_textinput").modal("show");
|
|
}
|
|
|
|
function showMessage(icon, title, message, size) {
|
|
$("#modal_message h4").html((icon == "") ? "" : '<span class="glyphicon glyphicon-' + icon + '"></span> ');
|
|
$("#modal_message h4").append(title);
|
|
$("#modal_message p").html(message);
|
|
$("#modal_message .modal-dialog").removeClass("modal-sm modal-lg");
|
|
if (size != "md") {
|
|
$("#modal_message .modal-dialog").addClass("modal-" + size);
|
|
}
|
|
$("#modal_message").modal("show");
|
|
}
|
|
|
|
function showPasswordPrompt() {
|
|
$('#input_password').val("");
|
|
$("#modal_pass_input").modal("show");
|
|
$("#modal_pass_input").one("hide.bs.modal", function() {
|
|
// The network request will take a few ms anyway, so no matter if the user has
|
|
// cancelled the password input, we can reset the Connect button here...
|
|
$(".btn-connect").removeClass("btn-warning disabled").addClass("btn-info").find("span:not(.glyphicon)").text(T("Connect"));
|
|
});
|
|
}
|
|
|
|
$("#modal_pass_input, #modal_textinput").on('shown.bs.modal', function() {
|
|
$(this).find("input").focus()
|
|
});
|
|
|
|
var elementToFocus;
|
|
|
|
$("#modal_message").on('shown.bs.modal', function() {
|
|
elementToFocus = $("body :focus");
|
|
$('#modal_message button').focus()
|
|
});
|
|
|
|
$("#modal_message").on('hidden.bs.modal', function() {
|
|
if (elementToFocus != undefined) {
|
|
elementToFocus.focus();
|
|
elementToFocus = undefined;
|
|
}
|
|
});
|
|
|
|
$("#form_password").submit(function(e) {
|
|
$("#modal_pass_input").off("hide.bs.modal").modal("hide");
|
|
connect($("#input_password").val(), false);
|
|
e.preventDefault();
|
|
});
|
|
|
|
/* GUI Helpers */
|
|
|
|
function addBedTemperature(temperature) {
|
|
// Drop-Down item
|
|
$(".ul-bed-temp").append('<li><a href="#" class="bed-temp" data-temp="' + temperature + '">' + temperature + ' °C</a></li>');
|
|
$(".btn-bed-temp").removeClass("disabled");
|
|
|
|
// Entry on Settings page
|
|
var item = '<li class="list-group-item col-md-6" data-temperature="' + temperature + '">' + temperature + ' °C';
|
|
item += '<button class="btn btn-danger btn-sm btn-delete-parent pull-right" title="' + T("Delete this temperature item") + '">';
|
|
item += '<span class="glyphicon glyphicon-trash"></span></button></li>';
|
|
$("#ul_bed_temps").append(item);
|
|
}
|
|
|
|
function addDefaultGCode(label, gcode) {
|
|
// Drop-Down item
|
|
var item = '<li><a href="#" class="gcode" data-gcode="' + gcode + '">';
|
|
item += '<span>' + label + '</span>';
|
|
item += '<span class="label label-primary">' + gcode + '</span>';
|
|
item += '</a></li>';
|
|
|
|
$(".ul-gcodes").append(item);
|
|
$(".btn-gcodes").removeClass("disabled");
|
|
|
|
// Entry on Settings page
|
|
item = '<tr><td><label class="label label-primary">' + gcode + '</label></td><td>' + label + '</td><td>';
|
|
item += '<button class="btn btn-sm btn-danger btn-delete-parent" title="' + T("Delete this G-Code item") + '">';
|
|
item += '<span class="glyphicon glyphicon-trash"></span></button></td></tr>';
|
|
$("#table_gcodes").append(item);
|
|
}
|
|
|
|
function addGCodeFile(filename) {
|
|
$("#page_files h1").addClass("hidden");
|
|
|
|
var row = '<tr data-item="' + filename + '"><td></td><td></td>';
|
|
row += '<td><span class="glyphicon glyphicon-asterisk"></span>' + filename + '</td>';
|
|
row += '<td class="hidden-xs">' + T("loading") + '</td>';
|
|
row += '<td>loading</td>';
|
|
row += '<td>loading</td>';
|
|
row += '<td>loading</td>';
|
|
row += '<td class="hidden-xs hidden-sm">' + T("loading") + '</td></tr>';
|
|
|
|
$("#table_gcode_files").removeClass("hidden");
|
|
return $(row).appendTo("#table_gcode_files");
|
|
}
|
|
|
|
function addMacroFile(filename) {
|
|
// Control Page
|
|
if (currentMacroDirectory == "/macros") {
|
|
var label = stripMacroFilename(filename);
|
|
var macroButton = '<div class="btn-group">';
|
|
macroButton += '<button class="btn btn-default btn-macro btn-sm" data-macro="/macros/' + filename + '">' + label + '</button>';
|
|
macroButton += '</div>';
|
|
|
|
$("#panel_macro_buttons h4").addClass("hidden");
|
|
$("#panel_macro_buttons .btn-group-vertical").append(macroButton);
|
|
}
|
|
|
|
// Macro Page
|
|
var row = '<tr data-item="' + filename + '"><td></td><td></td>';
|
|
row += '<td><span class="glyphicon glyphicon-asterisk"></span>' + filename + '</td>';
|
|
row += '<td>' + T("loading") + '</td></tr>';
|
|
|
|
$("#page_macros h1").addClass("hidden");
|
|
$("#table_macro_files").removeClass("hidden");
|
|
return $(row).appendTo("#table_macro_files");
|
|
}
|
|
|
|
function beep(frequency, duration) {
|
|
var context = new webkitAudioContext();
|
|
oscillator = context.createOscillator();
|
|
|
|
oscillator.type = 0; // sine wave: TODO add more possibilities to the Settings page
|
|
oscillator.frequency.value = frequency;
|
|
oscillator.connect(context.destination);
|
|
oscillator.noteOn && oscillator.noteOn(0);
|
|
|
|
setTimeout(function() {
|
|
oscillator.disconnect();
|
|
}, duration);
|
|
}
|
|
|
|
function addHeadTemperature(temperature, type) {
|
|
// Drop-Down item
|
|
$(".ul-" + type + "-temp").append('<li><a href="#" class="heater-temp" data-temp="' + temperature + '">' + temperature + ' °C</a></li>');
|
|
$(".btn-" + type + "-temp").removeClass("disabled");
|
|
|
|
// Entry on Settings page
|
|
var item = '<li class="list-group-item col-xs-6 col-lg-3" data-temperature="' + temperature + '">' + temperature + ' °C';
|
|
item += '<button class="btn btn-danger btn-sm btn-delete-parent pull-right" title="' + T("Delete this temperature item") + '">';
|
|
item += '<span class="glyphicon glyphicon-trash"></span></button></li>';
|
|
$("#ul_" + type + "_temps").append(item);
|
|
}
|
|
|
|
function changeTool(tool)
|
|
{
|
|
if (tool >= 0) {
|
|
if (getTool(tool).heaters.length > 0) {
|
|
// Tool macros are likely to block the HTTP G-Code processor, so we first turn off
|
|
// the appropriate heater, change the tool and then turn it back on.
|
|
var firstToolHeater = getTool(tool).heaters;
|
|
var gcode = "G10 P" + tool + " S-273\n" +
|
|
"T" + tool + "\n" +
|
|
"G10 P" + tool + " S" + $("#input_temp_h" + firstToolHeater + "_active").val();
|
|
sendGCode(gcode);
|
|
} else {
|
|
sendGCode("T" + tool);
|
|
}
|
|
} else {
|
|
sendGCode("T-1");
|
|
}
|
|
}
|
|
|
|
function clearBedTemperatures() {
|
|
$(".ul-bed-temp, #ul_bed_temps").html("");
|
|
$(".btn-bed-temp").addClass("disabled");
|
|
}
|
|
|
|
function clearGCodeDirectory() {
|
|
$("#ol_gcode_directory").children(":not(:last-child)").remove();
|
|
$("#ol_gcode_directory").prepend('<li class="active"><span class="glyphicon glyphicon-folder-open"></span> ' + T("G-Codes Directory") + '</li>');
|
|
}
|
|
|
|
function clearGCodeFiles() {
|
|
$("#table_gcode_files > tbody").remove();
|
|
$("#table_gcode_files").addClass("hidden");
|
|
$("#page_files h1").removeClass("hidden");
|
|
if (isConnected) {
|
|
$("#page_files h1").text(T("No Files or Directories found"));
|
|
} else {
|
|
$("#page_files h1").text(T("Connect to your Duet to display G-Code files"));
|
|
}
|
|
}
|
|
|
|
function clearDefaultGCodes() {
|
|
$(".ul-gcodes").html("");
|
|
$("#table_gcodes > tbody").remove();
|
|
$(".btn-gcodes").addClass("disabled");
|
|
}
|
|
|
|
function clearHeadTemperatures() {
|
|
$(".ul-active-temp, .ul-standby-temp, #ul_active_temps, #ul_standby_temps").html("");
|
|
$(".btn-active-temp, .btn-standby-temp").addClass("disabled");
|
|
}
|
|
|
|
function clearMacroDirectory() {
|
|
$("#ol_macro_directory").children(":not(:last-child)").remove();
|
|
$("#ol_macro_directory").prepend('<li class="active"><span class="glyphicon glyphicon-folder-open"></span> ' + T("Macros Directory") + '</li>');
|
|
}
|
|
|
|
function clearMacroFiles() {
|
|
// Control Page
|
|
if (currentMacroDirectory == "/macros") {
|
|
$("#panel_macro_buttons .btn-group-vertical").html("");
|
|
$("#panel_macro_buttons h4").removeClass("hidden");
|
|
}
|
|
|
|
// Macros Page
|
|
$("#table_macro_files > tbody").remove();
|
|
$("#table_macro_files").addClass("hidden");
|
|
$("#page_macros h1").removeClass("hidden");
|
|
if (isConnected) {
|
|
$("#page_macros h1").text(T("No Macro Files found"));
|
|
} else {
|
|
$("#page_macros h1").text(T("Connect to your Duet to display Macro files"));
|
|
}
|
|
}
|
|
|
|
function convertSeconds(value) {
|
|
value = Math.round(value);
|
|
if (value < 0) {
|
|
value = 0;
|
|
}
|
|
|
|
var timeLeft = [], temp;
|
|
if (value >= 3600) {
|
|
temp = Math.floor(value / 3600);
|
|
if (temp > 0) {
|
|
timeLeft.push(temp + "h");
|
|
value = value % 3600;
|
|
}
|
|
}
|
|
if (value >= 60) {
|
|
temp = Math.floor(value / 60);
|
|
if (temp > 0) {
|
|
timeLeft.push((temp > 9 ? temp : "0" + temp) + "m");
|
|
value = value % 60;
|
|
}
|
|
}
|
|
value = value.toFixed(0);
|
|
timeLeft.push((value > 9 ? value : "0" + value) + "s");
|
|
|
|
return timeLeft.reduce(function(a, b) { return a + " " + b; });
|
|
}
|
|
|
|
function formatSize(bytes) {
|
|
if (settings.useKiB) {
|
|
if (bytes > 1073741824) { // GiB
|
|
return (bytes / 1073741824).toFixed(1) + " GiB";
|
|
}
|
|
if (bytes > 1048576) { // MiB
|
|
return (bytes / 1048576).toFixed(1) + " MiB";
|
|
}
|
|
if (bytes > 1024) { // KiB
|
|
return (bytes / 1024).toFixed(1) + " KiB";
|
|
}
|
|
} else {
|
|
if (bytes > 1000000000) { // GB
|
|
return (bytes / 1000000000).toFixed(1) + " GB";
|
|
}
|
|
if (bytes > 1000000) { // MB
|
|
return (bytes / 1000000).toFixed(1) + " MB";
|
|
}
|
|
if (bytes > 1000) { // KB
|
|
return (bytes / 1000).toFixed(1) + " KB";
|
|
}
|
|
}
|
|
return bytes + " B";
|
|
}
|
|
|
|
function loadMacroDropdown(directory, dropdown) {
|
|
$.ajax("rr_files?dir=" + encodeURIComponent(directory), {
|
|
dataType: "json",
|
|
directory: directory,
|
|
dropdown: dropdown,
|
|
success: function(response) {
|
|
if (response.files.length == 0) {
|
|
dropdown.html('<li><a href="#" class="disabled" style="color:#777;">' + T("No files found!") + '</a></li>');
|
|
} else {
|
|
dropdown.html('<li><a href="#" class="disabled" style="color:#777;">' + directory + '</a></li><li class="divider"></li>');
|
|
var files = response.files.sort(function (a, b) {
|
|
return a.toLowerCase().localeCompare(b.toLowerCase());
|
|
});
|
|
|
|
files.forEach(function(filename) {
|
|
$.ajax("rr_fileinfo?name=" + encodeURIComponent(directory + "/" + filename), {
|
|
dataType: "json",
|
|
directory: directory,
|
|
dropdown: dropdown,
|
|
filename: filename,
|
|
success: function(fileinfo) {
|
|
var label = stripMacroFilename(filename);
|
|
if (fileinfo.err == 0) {
|
|
dropdown.append('<li><a href="#" class="macro-file-entry" data-macro="' + directory + '/' + filename + '">' + label + '</a></li>');
|
|
} else {
|
|
dropdown.append('<li><a href="#" class="macro-dir-entry" data-directory="' + directory + '/' + filename + '">' + label + ' <span class="caret"></span></a></li>');
|
|
}
|
|
|
|
$(".macro-file-entry").off("click").click(function(e) {
|
|
sendGCode("M98 P" + $(this).data("macro"));
|
|
e.preventDefault();
|
|
});
|
|
|
|
$(".macro-dir-entry").off("click").click(function(e) {
|
|
var dropdown = $(this).parents("ul");
|
|
loadMacroDropdown($(this).data("directory"), dropdown);
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function log(style, message) {
|
|
var entry = '<div class="row alert-' + style + '">';
|
|
entry += '<div class="col-xs-2 col-sm-2 col-md-2 col-lg-1 text-center"><strong>' + (new Date()).toLocaleTimeString() + '</strong></div>';
|
|
entry += '<div class="col-xs-10 col-sm-10 col-md-10 col-lg-11">' + message + '</div></div>';
|
|
$("#console_log").prepend(entry);
|
|
}
|
|
|
|
function recordHeaterTemperatures(bedTemp, chamberTemp, headTemps) {
|
|
// Add bed temperature
|
|
if (heatedBed) {
|
|
recordedBedTemperatures.push(bedTemp);
|
|
} else {
|
|
recordedBedTemperatures = [];
|
|
}
|
|
if (recordedBedTemperatures.length > maxTemperatureSamples) {
|
|
recordedBedTemperatures.shift();
|
|
}
|
|
|
|
// Add chamber temperature
|
|
if (chamber) {
|
|
recordedChamberTemperatures.push(chamberTemp);
|
|
} else {
|
|
recordedChamberTemperatures = [];
|
|
}
|
|
if (recordedChamberTemperatures.length > maxTemperatureSamples) {
|
|
recordedChamberTemperatures.shift();
|
|
}
|
|
|
|
// Add heater temperatures
|
|
for(var i=0; i<headTemps.length; i++) {
|
|
recordedHeadTemperatures[i].push(headTemps[i]);
|
|
if (recordedHeadTemperatures[i].length > maxTemperatureSamples) {
|
|
recordedHeadTemperatures[i].shift();
|
|
}
|
|
}
|
|
|
|
// Remove invalid data (in case the number of heads has changed)
|
|
for(var i=headTemps.length; i<6; i++) {
|
|
recordedHeadTemperatures[i] = [];
|
|
}
|
|
}
|
|
|
|
function setAxesHomed(axes) {
|
|
// Set button colors
|
|
var unhomedAxes = "";
|
|
if (axes[0]) {
|
|
$(".btn-home-x").removeClass("btn-warning").addClass("btn-primary");
|
|
} else {
|
|
unhomedAxes = (geometry == "delta") ? ", A" : ", X";
|
|
$(".btn-home-x").removeClass("btn-primary").addClass("btn-warning");
|
|
}
|
|
if (axes[1]) {
|
|
$(".btn-home-y").removeClass("btn-warning").addClass("btn-primary");
|
|
} else {
|
|
unhomedAxes += (geometry == "delta") ? ", B" : ", Y";
|
|
$(".btn-home-y").removeClass("btn-primary").addClass("btn-warning");
|
|
}
|
|
if (axes[2]) {
|
|
$(".btn-home-z").removeClass("btn-warning").addClass("btn-primary");
|
|
} else {
|
|
unhomedAxes += (geometry == "delta") ? ", C" : ", Z";
|
|
$(".btn-home-z").removeClass("btn-primary").addClass("btn-warning");
|
|
}
|
|
|
|
// Set home alert visibility
|
|
if (unhomedAxes == "") {
|
|
$(".home-warning").addClass("hidden");
|
|
} else {
|
|
if (unhomedAxes.length > 3) {
|
|
$("#unhomed_warning").html(T("The following axes are not homed: <strong>{0}</strong>", unhomedAxes.substring(2)));
|
|
} else {
|
|
$("#unhomed_warning").html(T("The following axis is not homed: <strong>{0}</strong>", unhomedAxes.substring(2)));
|
|
}
|
|
$(".home-warning").removeClass("hidden");
|
|
}
|
|
}
|
|
|
|
function setATXPower(value) {
|
|
$("input[name='atxPower']").prop("checked", false).parent().removeClass("active");
|
|
$("input[name='atxPower'][value='" + (value ? "1" : "0") + "']").prop("checked", true).parent().addClass("active");
|
|
}
|
|
|
|
function setCurrentTemperature(heater, temperature) {
|
|
var field = "#tr_head_" + heater + " td";
|
|
if (heater == "bed") {
|
|
field = "#tr_bed td";
|
|
} else if (heater == "chamber") {
|
|
field = "#tr_chamber td";
|
|
}
|
|
|
|
if (temperature == undefined) {
|
|
$(field).first().html("n/a");
|
|
} else if (temperature < -200) {
|
|
$(field).first().html("error");
|
|
} else {
|
|
$(field).first().html(temperature.toFixed(1) + " °C");
|
|
}
|
|
|
|
if (heater != "bed" && heater != "chamber" && lastStatusResponse != undefined) {
|
|
if (lastStatusResponse.currentTool != -1) {
|
|
var isActiveHead = false;
|
|
getToolsByHeater(heater).forEach(function(tool) { if (tool == lastStatusResponse.currentTool) { isActiveHead = true; } });
|
|
if (isActiveHead) {
|
|
if (temperature >= coldRetractTemp) {
|
|
$(".btn-retract").removeClass("disabled");
|
|
} else {
|
|
$(".btn-retract").addClass("disabled");
|
|
}
|
|
|
|
if (temperature >= coldExtrudeTemp) {
|
|
$(".btn-extrude").removeClass("disabled");
|
|
} else {
|
|
$(".btn-extrude").addClass("disabled");
|
|
}
|
|
}
|
|
} else {
|
|
$(".btn-retract, .btn-extrude").addClass("disabled");
|
|
}
|
|
}
|
|
}
|
|
|
|
function setGeometry(g) {
|
|
// The following may be extended in future versions
|
|
if (g == "delta") {
|
|
$("#btn_bed_compensation").text(T("Auto Delta Calibration"));
|
|
$(".home-buttons div, div.home-buttons").addClass("hidden");
|
|
$("td.home-buttons").css("padding-right", "0px");
|
|
$("#btn_homeall").css("min-width", "");
|
|
} else {
|
|
$("#btn_bed_compensation").text(T("Auto Bed Compensation"));
|
|
$(".home-buttons div, div.home-buttons").removeClass("hidden");
|
|
$("td.home-buttons").css("padding-right", "");
|
|
$("#btn_homeall").resize();
|
|
}
|
|
$("#dd_geometry").text(T(g.charAt(0).toUpperCase() + g.slice(1)));
|
|
geometry = g;
|
|
}
|
|
|
|
function setGCodeFileItem(row, size, height, firstLayerHeight, layerHeight, filamentUsage, generatedBy) {
|
|
row.data("file", row.data("item"));
|
|
row.children().eq(0).html('<button class="btn btn-success btn-print-file btn-sm" title="' + T("Print this file (M32)") + '"><span class="glyphicon glyphicon-print"></span></button>').attr("colspan", "");
|
|
row.children().eq(1).html('<button class="btn btn-danger btn-delete-file btn-sm" title="' + T("Delete this file") + '"><span class="glyphicon glyphicon-trash"></span></button>');
|
|
|
|
var linkCell = row.children().eq(2);
|
|
linkCell.find("span").removeClass("glyphicon-asterisk").addClass("glyphicon-file");
|
|
linkCell.html('<a href="#" class="gcode-file">' + linkCell.html() + '</a>');
|
|
linkCell.find("a")[0].addEventListener("dragstart", fileDragStart, false);
|
|
linkCell.find("a")[0].addEventListener("dragend", fileDragEnd, false);
|
|
|
|
row.children().eq(3).html(formatSize(size));
|
|
|
|
if (height > 0) {
|
|
row.children().eq(4).html(height + " mm");
|
|
} else {
|
|
row.children().eq(4).html("n/a");
|
|
}
|
|
|
|
if (layerHeight > 0) {
|
|
if (firstLayerHeight == undefined) {
|
|
row.children().eq(5).html(layerHeight + " mm");
|
|
} else {
|
|
row.children().eq(5).html(firstLayerHeight + " / " + layerHeight + " mm");
|
|
}
|
|
} else {
|
|
row.children().eq(5).html("n/a");
|
|
}
|
|
|
|
if (filamentUsage.length > 0) {
|
|
var totalUsage = filamentUsage.reduce(function(a, b) { return a + b; }).toFixed(1) + " mm";
|
|
if (filamentUsage.length == 1) {
|
|
row.children().eq(6).html(totalUsage);
|
|
} else {
|
|
var individualUsage = filamentUsage.reduce(function(a, b) { return a + " mm, " + b; }) + " mm";
|
|
var filaUsage = "<abbr class=\"filament-usage\" title=\"" + individualUsage + "\">" + totalUsage + "</abbr>";
|
|
row.children().eq(6).html(filaUsage);
|
|
}
|
|
} else {
|
|
row.children().eq(6).html("n/a");
|
|
}
|
|
|
|
if (generatedBy != "") {
|
|
row.children().eq(7).html(generatedBy);
|
|
} else {
|
|
row.children().eq(7).html("n/a");
|
|
}
|
|
}
|
|
|
|
function setGCodeDirectoryItem(row) {
|
|
row.data("directory", row.data("item"));
|
|
row.children().eq(1).html('<button class="btn btn-danger btn-delete-gcode-directory btn-sm" title="' + T("Delete this directory") + '"><span class="glyphicon glyphicon-trash"></span></button>');
|
|
|
|
var linkCell = row.children().eq(2);
|
|
linkCell.find("span").removeClass("glyphicon-asterisk").addClass("glyphicon-folder-open");
|
|
linkCell.html('<a href="#" class="gcode-directory">' + linkCell.html() + '</a>').prop("colspan", 6);
|
|
linkCell.find("a")[0].addEventListener("dragstart", fileDragStart, false);
|
|
linkCell.find("a")[0].addEventListener("dragend", fileDragEnd, false);
|
|
|
|
for(var i=8; i>=3; i--) {
|
|
row.children().eq(i).remove();
|
|
}
|
|
|
|
if (gcodeLastDirectory == undefined) {
|
|
var firstRow = $("#table_gcode_files tbody > tr:first-child");
|
|
if (firstRow != row) {
|
|
row.insertBefore(firstRow);
|
|
}
|
|
} else {
|
|
row.insertAfter(gcodeLastDirectory);
|
|
}
|
|
gcodeLastDirectory = row;
|
|
}
|
|
|
|
function setGCodeDirectory(directory) {
|
|
currentGCodeDirectory = directory;
|
|
|
|
$("#ol_gcode_directory").children(":not(:last-child)").remove();
|
|
if (directory == "/gcodes") {
|
|
$("#ol_gcode_directory").prepend('<li class="active"><span class="glyphicon glyphicon-folder-open"></span> ' + T("G-Codes Directory") + '</li>');
|
|
$("#ol_gcode_directory li:last-child").html('<span class="glyphicon glyphicon-level-up"></span> ' + T("Go Up"));
|
|
} else {
|
|
var listContent = '<li><a href="#" data-directory="/gcodes"><span class="glyphicon glyphicon-folder-open"></span> ' + T("G-Codes Directory") + '</a></li>';
|
|
var directoryItems = directory.split("/"), directoryPath = "/gcodes";
|
|
for(var i=2; i<directoryItems.length -1; i++) {
|
|
directoryPath += "/" + directoryItems[i];
|
|
listContent += '<li class="active"><a href="#" data-directory="' + directoryPath + '">' + directoryItems[i] + '</a></li>';
|
|
}
|
|
listContent += '<li class="active">' + directoryItems[directoryItems.length -1] + '</li>';
|
|
$("#ol_gcode_directory").prepend(listContent);
|
|
$("#ol_gcode_directory li:last-child").html('<a href="#" data-directory="' + directoryPath + '"><span class="glyphicon glyphicon-level-up"></span> ' + T("Go Up") + '</a>');
|
|
}
|
|
}
|
|
|
|
function setHeaterState(heater, status, currentTool) {
|
|
var statusText = "n/a";
|
|
switch (status) {
|
|
case 0:
|
|
statusText = T("off");
|
|
break;
|
|
|
|
case 1:
|
|
statusText = T("standby");
|
|
break;
|
|
|
|
case 2:
|
|
statusText = T("active");
|
|
break;
|
|
|
|
case 3:
|
|
statusText = T("fault");
|
|
break;
|
|
}
|
|
|
|
if (heater == "bed") {
|
|
$("#tr_bed > th:first-child > span").text(statusText);
|
|
} else if (heater == "chamber") {
|
|
$("#tr_chamber > th:first-child > span").text(statusText);
|
|
} else {
|
|
var tools = getToolsByHeater(heater);
|
|
if (tools.length != 0) {
|
|
statusText += " (T" + tools.reduce(function(a, b) { return a + ", T" + b; }) + ")";
|
|
statusText = statusText.replace("T" + currentTool, "<u>T" + currentTool + "</u>");
|
|
if (tools.length > 1) {
|
|
$("#table_heaters tr > th:first-child").eq(heater).find(".caret").removeClass("hidden");
|
|
} else {
|
|
$("#table_heaters tr > th:first-child").eq(heater).find(".caret").addClass("hidden");
|
|
}
|
|
} else {
|
|
$("#table_heaters tr > th:first-child").eq(heater).find(".caret").addClass("hidden");
|
|
}
|
|
$("#table_heaters tr > th:first-child").eq(heater).children("span").html(statusText);
|
|
}
|
|
}
|
|
|
|
function setMacroFileItem(row, size) {
|
|
row.data("file", row.data("item"));
|
|
row.children().eq(0).html('<button class="btn btn-success btn-run-macro btn-sm" title="' + T("Run this macro file (M98)") + '"><span class="glyphicon glyphicon-play"></span></button>');
|
|
row.children().eq(1).html('<button class="btn btn-danger btn-delete-macro btn-sm" title="' + T("Delete this macro") + '"><span class="glyphicon glyphicon-trash"></span></button>');
|
|
|
|
var linkCell = row.children().eq(2);
|
|
linkCell.find("span").removeClass("glyphicon-asterisk").addClass("glyphicon-file");
|
|
linkCell.html('<a href="#" class="btn-run-macro">' + linkCell.html() + '</a>');
|
|
linkCell.find("a")[0].addEventListener("dragstart", fileDragStart, false);
|
|
linkCell.find("a")[0].addEventListener("dragend", fileDragEnd, false);
|
|
|
|
row.children().eq(3).html(formatSize(size));
|
|
}
|
|
|
|
function setMacroDirectoryItem(row) {
|
|
if (currentMacroDirectory == "/macros") {
|
|
var button = $("#panel_macro_buttons button[data-macro='" + currentMacroDirectory + "/" + row.data("item") + "']");
|
|
button.html(button.html() + ' <span class="caret"></span>');
|
|
button.data("directory", button.data("macro")).attr("data-toggle", "dropdown");
|
|
button.removeData("macro");
|
|
button.parent().append('<ul class="dropdown-menu"></ul>');
|
|
}
|
|
|
|
row.data("directory", row.data("item"));
|
|
row.children().eq(1).html('<button class="btn btn-danger btn-delete-macro-directory btn-sm" title="' + T("Delete this directory") + '"><span class="glyphicon glyphicon-trash"></span></button>');
|
|
|
|
var linkCell = row.children().eq(2);
|
|
linkCell.find("span").removeClass("glyphicon-asterisk").addClass("glyphicon-folder-open");
|
|
linkCell.html('<a href="#" class="macro-directory">' + linkCell.html() + '</a>').prop("colspan", 2);
|
|
linkCell.find("a")[0].addEventListener("dragstart", fileDragStart, false);
|
|
linkCell.find("a")[0].addEventListener("dragend", fileDragEnd, false);
|
|
|
|
row.children().eq(3).remove();
|
|
|
|
if (macroLastDirectory == undefined) {
|
|
var firstRow = $("#table_macro_files tbody > tr:first-child");
|
|
if (firstRow != row) {
|
|
row.insertBefore(firstRow);
|
|
}
|
|
} else {
|
|
row.insertAfter(macroLastDirectory);
|
|
}
|
|
macroLastDirectory = row;
|
|
}
|
|
|
|
function setMacroDirectory(directory) {
|
|
currentMacroDirectory = directory;
|
|
|
|
$("#ol_macro_directory").children(":not(:last-child)").remove();
|
|
if (directory == "/macros") {
|
|
$("#ol_macro_directory").prepend('<li class="active"><span class="glyphicon glyphicon-folder-open"></span> ' + T("Macros Directory") + '</li>');
|
|
$("#ol_macro_directory li:last-child").html('<span class="glyphicon glyphicon-level-up"></span> ' + T("Go Up"));
|
|
} else {
|
|
var listContent = '<li><a href="#" data-directory="/macros"><span class="glyphicon glyphicon-folder-open"></span> ' + T("Macros Directory") + '</a></li>';
|
|
var directoryItems = directory.split("/"), directoryPath = "/macros";
|
|
for(var i=2; i<directoryItems.length -1; i++) {
|
|
directoryPath += "/" + directoryItems[i];
|
|
listContent += '<li class="active"><a href="#" data-directory="' + directoryPath + '">' + directoryItems[i] + '</a></li>';
|
|
}
|
|
listContent += '<li class="active">' + directoryItems[directoryItems.length -1] + '</li>';
|
|
$("#ol_macro_directory").prepend(listContent);
|
|
$("#ol_macro_directory li:last-child").html('<a href="#" data-directory="' + directoryPath + '"><span class="glyphicon glyphicon-level-up"></span> ' + T("Go Up") + '</a>');
|
|
}
|
|
}
|
|
|
|
function setPauseStatus(paused) {
|
|
if (paused == isPaused) {
|
|
return;
|
|
}
|
|
|
|
if (paused) {
|
|
$("#btn_cancel").removeClass("disabled").parents("div.btn-group").removeClass("hidden");
|
|
$("#btn_pause").removeClass("btn-warning disabled").addClass("btn-success").text(T("Resume")).attr("title", T("Resume paused print (M24)"));
|
|
} else {
|
|
$("#btn_cancel").parents("div.btn-group").addClass("hidden");
|
|
$("#btn_pause").removeClass("btn-success").addClass("btn-warning").text(T("Pause Print")).attr("title", T("Pause current print (M25)"));
|
|
if (isPrinting) {
|
|
$("#btn_pause").removeClass("disabled");
|
|
}
|
|
}
|
|
isPaused = paused;
|
|
}
|
|
|
|
function setPrintStatus(printing) {
|
|
if (printing == isPrinting) {
|
|
return;
|
|
}
|
|
|
|
if (printing) {
|
|
if (justConnected) {
|
|
showPage("print");
|
|
}
|
|
|
|
layerData = [];
|
|
currentLayerTime = maxLayerTime = lastLayerPrintDuration = 0;
|
|
drawPrintChart();
|
|
printHasFinished = false;
|
|
|
|
$(".btn-upload").addClass("disabled");
|
|
$("#page_general .btn-upload").removeClass("disabled");
|
|
|
|
$("#btn_pause").removeClass("disabled");
|
|
$(".row-progress").removeClass("hidden");
|
|
$("#td_last_layertime").html("n/a");
|
|
|
|
requestFileInfo();
|
|
} else {
|
|
$("#btn_pause").addClass("disabled");
|
|
$(".btn-upload").removeClass("disabled");
|
|
|
|
if (!isConnected || fileInfo == undefined) {
|
|
$(".row-progress").addClass("hidden");
|
|
}
|
|
|
|
if (isConnected) {
|
|
if ($("#auto_sleep").is(":checked")) {
|
|
sendGCode("M1");
|
|
$("#auto_sleep").prop("checked", false);
|
|
}
|
|
|
|
if (!printHasFinished && currentLayerTime > 0) {
|
|
addLayerData(currentLayerTime, true);
|
|
$("#td_layertime").html("n/a");
|
|
}
|
|
printHasFinished = true;
|
|
|
|
if (fileInfo != undefined) {
|
|
setProgress(100, T("Printed {0}, 100% Complete", fileInfo.fileName), undefined);
|
|
} else {
|
|
setProgress(100, T("Print Complete!"), undefined);
|
|
}
|
|
|
|
["filament", "layer", "file"].forEach(function(id) {
|
|
if ($("#tl_" + id).html() != "n/a") {
|
|
$("#tl_" + id).html("00s");
|
|
$("#et_" + id).html((new Date()).toLocaleTimeString());
|
|
}
|
|
});
|
|
}
|
|
|
|
fileInfo = undefined;
|
|
}
|
|
|
|
isPrinting = printing;
|
|
|
|
if (waitingForPrintStart && printing) {
|
|
$("#modal_upload").modal("hide");
|
|
showPage("print");
|
|
waitingForPrintStart = false;
|
|
}
|
|
}
|
|
|
|
function setProbeValue(value, secondaryValue) {
|
|
if (value < 0) {
|
|
$("#td_probe").html("n/a");
|
|
} else if (secondaryValue == undefined) {
|
|
$("#td_probe").html(value);
|
|
} else {
|
|
$("#td_probe").html(value + " (" + secondaryValue.reduce(function(a, b) { return a + b; }) + ")");
|
|
}
|
|
|
|
if (probeTriggerValue != undefined && value > probeTriggerValue && !isPrinting) {
|
|
$("#td_probe").css("background-color", probeTriggerColor);
|
|
} else if (probeSlowDownValue != undefined && value > probeSlowDownValue && !isPrinting) {
|
|
$("#td_probe").css("background-color", probeSlowDownColor);
|
|
} else {
|
|
$("#td_probe").css("background-color", "");
|
|
}
|
|
}
|
|
|
|
function setProgress(progress, labelLeft, labelRight) {
|
|
if (labelLeft != undefined) {
|
|
$("#span_progress_left").text(labelLeft);
|
|
}
|
|
if (labelRight != undefined) {
|
|
$("#span_progress_right").text(labelRight);
|
|
}
|
|
$("#progress").css("width", progress + "%");
|
|
}
|
|
|
|
function setStatusLabel(text, style) {
|
|
text = T(text);
|
|
$(".label-status").removeClass("label-default label-danger label-info label-warning label-success").addClass("label-" + style).text(text);
|
|
}
|
|
|
|
function setTemperatureInput(head, value, active) {
|
|
var tempInputId;
|
|
|
|
if (head == "bed") {
|
|
tempInputId = "#input_temp_bed";
|
|
} else if (head == "chamber") {
|
|
tempInputId = "#input_temp_chamber";
|
|
} else {
|
|
tempInputId = "#input_temp_h" + head + "_";
|
|
tempInputId += (active) ? "active": "standby";
|
|
}
|
|
|
|
if (!$(tempInputId).is(":focus")) {
|
|
$(tempInputId).val((value < 0) ? 0 : value);
|
|
}
|
|
}
|
|
|
|
function setTimeLeft(field, value) {
|
|
if (value == undefined || (value == 0 && isPrinting)) {
|
|
$("#et_" + field + ", #tl_" + field).html("n/a");
|
|
} else {
|
|
// Estimate end time
|
|
var now = new Date();
|
|
var estEndTime = new Date(now.getTime() + value * 1000); // Date uses ms
|
|
$("#et_" + field).html(estEndTime.toLocaleTimeString());
|
|
|
|
// Estimate time left
|
|
$("#tl_" + field).html(convertSeconds(value));
|
|
}
|
|
}
|
|
|
|
function setTitle(title) {
|
|
$(".machine-name").html(title);
|
|
$("head > title").text(title);
|
|
}
|
|
|
|
function showPage(name) {
|
|
$(".navitem, .page").removeClass("active");
|
|
$(".navitem-" + name + ", #page_" + name).addClass("active");
|
|
|
|
if (name != currentPage) {
|
|
if (name == "control") {
|
|
$("#slider_fan_control").slider("relayout");
|
|
if (macroUpdateIndex != knownMacroFiles.length) {
|
|
updateMacroFiles();
|
|
}
|
|
}
|
|
|
|
if (name == "print") {
|
|
$("#slider_speed").slider("relayout");
|
|
$("#slider_fan_print").slider("relayout");
|
|
for(var extr=1; extr<=6; extr++) {
|
|
$("#slider_extr_" + extr).slider("relayout");
|
|
}
|
|
if (refreshPrintChart) {
|
|
drawPrintChart();
|
|
}
|
|
waitingForPrintStart = false;
|
|
}
|
|
|
|
if (name == "console") {
|
|
currentPage = "console";
|
|
if (window.matchMedia('(min-width: 992px)').matches) {
|
|
$("#page_console input").focus();
|
|
}
|
|
}
|
|
|
|
if (name == "files") {
|
|
if (gcodeUpdateIndex == knownGCodeFiles.length) {
|
|
$(".span-refresh-files").removeClass("hidden");
|
|
} else {
|
|
updateGCodeFiles();
|
|
}
|
|
} else {
|
|
$(".span-refresh-files").addClass("hidden");
|
|
}
|
|
|
|
if (name == "macros") {
|
|
if (macroUpdateIndex == knownMacroFiles.length) {
|
|
$(".span-refresh-macros").removeClass("hidden");
|
|
} else {
|
|
updateMacroFiles();
|
|
}
|
|
} else {
|
|
$(".span-refresh-macros").addClass("hidden");
|
|
}
|
|
|
|
if (name == "settings" && isConnected) {
|
|
getConfigResponse();
|
|
}
|
|
}
|
|
|
|
// Scroll to top of the main content on small devices
|
|
if (window.matchMedia('(max-width: 991px)').matches) {
|
|
var offset = (name != "control") ? -9 : 0;
|
|
$('html, body').animate({
|
|
scrollTop: ($('#main_content').offset().top + offset)
|
|
}, 500);
|
|
}
|
|
currentPage = name;
|
|
}
|
|
|
|
function stripMacroFilename(filename) {
|
|
var match = filename.match(/(.*)\.\w+/);
|
|
if (match == null) {
|
|
label = filename;
|
|
} else {
|
|
label = match[1];
|
|
}
|
|
|
|
match = label.match(/\d+_(.*)/);
|
|
if (match != null) {
|
|
label = match[1];
|
|
}
|
|
|
|
return label;
|
|
}
|
|
|
|
/* Other */
|
|
|
|
function applyThemeColors(themeActive) {
|
|
// Update temp chart colors and repaint it
|
|
tempChartOptions.colors[0] = $("#tr_bed a").css("color");
|
|
tempChartOptions.colors[1] = $("#tr_head_1 a").css("color");
|
|
tempChartOptions.colors[2] = $("#tr_head_2 a").css("color");
|
|
tempChartOptions.colors[3] = $("#tr_head_3 a").css("color");
|
|
tempChartOptions.colors[4] = $("#tr_head_4 a").css("color");
|
|
tempChartOptions.colors[5] = $("#tr_head_5 a").css("color");
|
|
tempChartOptions.colors[6] = $("#tr_chamber th").css("color");
|
|
if (tempChart != undefined) {
|
|
tempChart.destroy();
|
|
tempChart = undefined;
|
|
drawTemperatureChart();
|
|
}
|
|
|
|
// Update layer times chart
|
|
printChartOptions.colors[0] = getColorFromCSS("chart-print-line");
|
|
if (printChart != undefined) {
|
|
printChart.destroy();
|
|
printChart = undefined;
|
|
drawPrintChart();
|
|
}
|
|
|
|
if (themeActive) {
|
|
$("#layer_tooltip").css("background-color", $("#panel_print_info").css("background-color"));
|
|
} else {
|
|
$("#layer_tooltip").css("background-color", "");
|
|
}
|
|
|
|
// Update Z-probe colors
|
|
probeSlowDownColor = getColorFromCSS("probe-slow-down");
|
|
probeTriggerColor = getColorFromCSS("probe-trigger");
|
|
}
|
|
|
|
function getColorFromCSS(classname)
|
|
{
|
|
var ghostSpan = $('<span class="hidden ' + classname + '"></span>');
|
|
ghostSpan.appendTo("body");
|
|
var color = ghostSpan.css("color");
|
|
ghostSpan.remove();
|
|
return color;
|
|
}
|
|
|
|
// vim: ts=4:sw=4
|