ENH: new wiping dialog
1.Enhance performance and ui display jira: None Signed-off-by: xun.zhang <xun.zhang@bambulab.com> Change-Id: If1cde4d1a17437ee5485dd51adff4c3444774ffd
This commit is contained in:
parent
bc446854ff
commit
9c28c320d6
|
@ -0,0 +1,645 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
background: #f5f5f5;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
background: #fff;
|
||||||
|
padding: 20px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
max-width:fit-content(1000px);
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-panel {
|
||||||
|
background: #eeeeee;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-container {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 500px;
|
||||||
|
overflow: auto;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
position: relative;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
text-align: center;
|
||||||
|
padding: 2px;
|
||||||
|
position: relative;
|
||||||
|
width: 40px;
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead th {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
background: #eee;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody th {
|
||||||
|
position: sticky;
|
||||||
|
left: 0;
|
||||||
|
background: #eee;
|
||||||
|
z-index: 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:nth-child(even) {
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:nth-child(odd) {
|
||||||
|
background: #eeeeee;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody td:first-child,
|
||||||
|
thead th:first-child {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background: #eee;
|
||||||
|
z-index: 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-button {
|
||||||
|
display: inline-block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border: 1px solid #999;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 15px;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: default;
|
||||||
|
user-select: none;
|
||||||
|
padding: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"].table-input {
|
||||||
|
width: 30px;
|
||||||
|
height: 20px;
|
||||||
|
text-align: center;
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
appearance: textfield;
|
||||||
|
border: none;
|
||||||
|
background-color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"].table-input::-webkit-inner-spin-button,
|
||||||
|
input[type="number"].table-input::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-text {
|
||||||
|
color: red;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.normal-text {
|
||||||
|
color: black;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-gap {
|
||||||
|
width: 10px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 6px 9px;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-ok {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #21a452;
|
||||||
|
}
|
||||||
|
.btn-ok:hover {
|
||||||
|
background-color: #3dcb73;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-cancel {
|
||||||
|
color: black;
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
.btn-cancel:hover {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: 6px 9px;
|
||||||
|
border: 1px solid #dbdbdb;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
appearance: auto;
|
||||||
|
background-color: white;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
select option {
|
||||||
|
background-color: white;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
select:hover,
|
||||||
|
select:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #00ae42;
|
||||||
|
background-color: #edfaf2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 10px;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 暗色模式样式 */
|
||||||
|
body.dark-mode {
|
||||||
|
background-color: #2d2d31;
|
||||||
|
color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .container {
|
||||||
|
background: inherit;
|
||||||
|
border-color: #2d2d31;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .tip-panel {
|
||||||
|
background: #4c4c55;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .scroll-container {
|
||||||
|
border-color: #4c4c55;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode table {
|
||||||
|
background: inherit;
|
||||||
|
border-color: #4c4c55;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode th, body.dark-mode td {
|
||||||
|
background: inherit;
|
||||||
|
border-color: #555;
|
||||||
|
color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode thead th{
|
||||||
|
position: sticky;
|
||||||
|
z-index: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode tbody th{
|
||||||
|
position: sticky;
|
||||||
|
z-index: 9
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode tbody tr:nth-child(even) {
|
||||||
|
background: #2d2d31;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode tbody tr:nth-child(odd) {
|
||||||
|
background: #4c4c55;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode tbody td:first-child,
|
||||||
|
body.dark-mode thead th:first-child {
|
||||||
|
position: sticky;
|
||||||
|
z-index: 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .btn-ok {
|
||||||
|
background-color: #3a8f44;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .btn-dark {
|
||||||
|
background-color: #34495e;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode select {
|
||||||
|
background-color: #2d2d31;
|
||||||
|
color: white;
|
||||||
|
border-color: #4c4c55;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .warning-text {
|
||||||
|
color: #f44336;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .normal-text {
|
||||||
|
color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .icon-button {
|
||||||
|
background-color: #4c4c55;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="tip-panel" id="auto_flush_tip">
|
||||||
|
Studio would re-calculate your flushing volumes every time the filament
|
||||||
|
color changed or filaments changed. You could disable the auto-calculate
|
||||||
|
in Bambu Studio > Preferences.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-bottom: 10px; ">
|
||||||
|
<button
|
||||||
|
class="btn btn-ok"
|
||||||
|
onclick="calcFlushingVolumes()"
|
||||||
|
id="calc_btn"
|
||||||
|
>
|
||||||
|
Re-Calculate
|
||||||
|
</button>
|
||||||
|
<select
|
||||||
|
id="extruders"
|
||||||
|
onchange="handleExtruderSelect(document.getElementById('extruders').value)"
|
||||||
|
>
|
||||||
|
<option value="left" id="extruder_label_0">Left Nozzle</option>
|
||||||
|
<option value="right" id="extruder_label_1">Right Nozzle</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="scroll-container">
|
||||||
|
<table id="flushTable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 10px;">
|
||||||
|
<div id="volume_desp_panel" class="normal-text">
|
||||||
|
Flushing volume (mm³) for each filament pair.
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="volume_range_panel"
|
||||||
|
class="normal-text"
|
||||||
|
style="margin-top: 5px;"
|
||||||
|
>
|
||||||
|
Suggestion: Flushing Volume in range [50, 999]
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 8px;">
|
||||||
|
<label
|
||||||
|
for="multiplierInput"
|
||||||
|
id="multiplier_label"
|
||||||
|
style="font-size: 12px;"
|
||||||
|
>Multiplier</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
step="0.1"
|
||||||
|
id="multiplierInput"
|
||||||
|
style="width:70px;"
|
||||||
|
value="1.00"
|
||||||
|
oninput="onMultiplierChange()"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style="margin-top: 5px; margin-bottom: 5px; color: #666; font-size: 12px;"
|
||||||
|
id="multiplier_range_panel"
|
||||||
|
>
|
||||||
|
The multiplier should be in range [0.50, 3.00].
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="button-container" style="padding: 0px; margin: 0px;">
|
||||||
|
<button class="btn btn-ok" id="ok_btn" style="width: 60px; height: 30px; font-size: 12px; text-align: center;" onclick="storeData()">
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-cancel" id="cancel_btn" style="width: 60px; height: 30px; font-size: 12px; text-align: center;" onclick="quit()">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let m_number_of_filaments // 材料数量
|
||||||
|
let m_number_of_extruders // 喷嘴数量
|
||||||
|
let m_colours // 颜色
|
||||||
|
let m_display_matrix // 显示的矩阵
|
||||||
|
let m_raw_matrix // 原始数据
|
||||||
|
let m_flush_multipiers // 冲刷系数
|
||||||
|
let m_cell_inputs = []; //显示的内容
|
||||||
|
let m_curr_extruder_id = 0
|
||||||
|
let m_min_flush_volumes = []
|
||||||
|
let m_max_flush_volumes = []
|
||||||
|
let m_min_flush_multiplier = 0.50
|
||||||
|
let m_max_flush_multiplier = 3
|
||||||
|
|
||||||
|
function storeData() {
|
||||||
|
var data = JSON.stringify({
|
||||||
|
msg: 'storeData',
|
||||||
|
number_of_extruders: m_number_of_extruders,
|
||||||
|
raw_matrix: m_raw_matrix,
|
||||||
|
flush_multiplier: m_flush_multipiers
|
||||||
|
})
|
||||||
|
window.wipingDialog.postMessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function quit() {
|
||||||
|
var data = JSON.stringify({
|
||||||
|
msg: 'quit'
|
||||||
|
})
|
||||||
|
window.wipingDialog.postMessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function calcFlushingVolumes() {
|
||||||
|
var data = JSON.stringify({
|
||||||
|
msg: 'updateMatrix',
|
||||||
|
extruder_id: m_curr_extruder_id
|
||||||
|
})
|
||||||
|
window.wipingDialog.postMessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTable(dataMatrix, extruder_id) {
|
||||||
|
for (let i = 0; i < m_number_of_filaments; i++) {
|
||||||
|
for (let j = 0; j < m_number_of_filaments; j++) {
|
||||||
|
var newValue
|
||||||
|
var index = m_number_of_filaments * i + j
|
||||||
|
newValue = (i == j ? 0 : rawToDislay(dataMatrix[index] ,m_flush_multipiers[extruder_id]))
|
||||||
|
newValue = limitDisplayVal(newValue,extruder_id)
|
||||||
|
m_cell_inputs[i][j].value = newValue;
|
||||||
|
m_display_matrix[index] = newValue;
|
||||||
|
m_raw_matrix[extruder_id][index] = dataMatrix[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateWarningTexts();
|
||||||
|
}
|
||||||
|
|
||||||
|
// const virtual_data = {
|
||||||
|
// filament_colors: [
|
||||||
|
// '#123456', '#7890AB', '#CDEF01', '#F1A2B3', '#4D8B72', '#D9E1F2', '#B76C8C', '#A9C3D3',
|
||||||
|
// '#FF5733', '#33FF57', '#5733FF', '#FF33FF', '#FFFF33', '#33FFFF', '#FF5733', '#3333FF'
|
||||||
|
// ],
|
||||||
|
// extruder_num: 2,
|
||||||
|
// flush_volume_matrixs: [
|
||||||
|
// Array.from({ length: 256 }, () => Math.floor(Math.random() * 1000)),
|
||||||
|
// Array.from({ length: 256 }, () => Math.floor(Math.random() * 1000))
|
||||||
|
// ],
|
||||||
|
// flush_multiplier:[1,1]
|
||||||
|
// }
|
||||||
|
window.addEventListener("DOMContentLoaded",function(){
|
||||||
|
var data = JSON.stringify({
|
||||||
|
msg: 'init',
|
||||||
|
})
|
||||||
|
window.wipingDialog.postMessage(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
function buildText(data) {
|
||||||
|
document.getElementById('volume_desp_panel').innerText = data.volume_desp_panel
|
||||||
|
document.getElementById('volume_range_panel').innerText = data.volume_range_panel
|
||||||
|
document.getElementById('multiplier_range_panel').innerText = data.multiplier_range_panel
|
||||||
|
document.getElementById('auto_flush_tip').innerText = data.auto_flush_tip
|
||||||
|
document.getElementById('calc_btn').innerText = data.calc_btn_panel
|
||||||
|
document.getElementById('extruder_label_0').innerText = data.extruder_label_0
|
||||||
|
document.getElementById('extruder_label_1').innerText = data.extruder_label_1
|
||||||
|
document.getElementById('multiplier_label').innerText = data.multiplier_label
|
||||||
|
document.getElementById('ok_btn').innerText = data.ok_btn_label
|
||||||
|
document.getElementById('cancel_btn').innerText = data.cancel_btn_label
|
||||||
|
updateVolumeRange(m_min_flush_volumes[m_curr_extruder_id],m_max_flush_volumes[m_curr_extruder_id])
|
||||||
|
updateMultiplierRange(m_min_flush_multiplier,m_max_flush_multiplier)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算亮度
|
||||||
|
function getLuminance(color) {
|
||||||
|
const hex = color.replace(/^#/, '');
|
||||||
|
const r = parseInt(hex.slice(0, 2), 16);
|
||||||
|
const g = parseInt(hex.slice(2, 4), 16);
|
||||||
|
const b = parseInt(hex.slice(4, 6), 16);
|
||||||
|
return (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updateVolumeRange(min_volume,max_volume){
|
||||||
|
const panel = document.getElementById('volume_range_panel');
|
||||||
|
panel.innerText = panel.innerText.replace(/\[.*\]/, `[${min_volume}, ${max_volume}]`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateMultiplierRange(min_multiplier,max_multiplier){
|
||||||
|
const panel = document.getElementById('multiplier_range_panel');
|
||||||
|
panel.innerText = panel.innerText.replace(/\[.*\]/, `[${min_multiplier}, ${max_multiplier}]`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateFlushMultiplier(extruder_id){
|
||||||
|
document.getElementById("multiplierInput").value = m_flush_multipiers[extruder_id]
|
||||||
|
}
|
||||||
|
|
||||||
|
function rawToDislay(val, ratio){
|
||||||
|
return Math.round(val * ratio)
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayToRaw(val, ratio){
|
||||||
|
if(ratio==0)
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return Math.round(val / ratio)
|
||||||
|
}
|
||||||
|
|
||||||
|
function limitDisplayVal(val,extruder_id){
|
||||||
|
if (isNaN(val))
|
||||||
|
return 0
|
||||||
|
if (val < 0)
|
||||||
|
return 0
|
||||||
|
if (val > m_max_flush_volumes[extruder_id])
|
||||||
|
return m_max_flush_volumes[extruder_id];
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildTable(data) {
|
||||||
|
m_colours = data.filament_colors
|
||||||
|
m_number_of_extruders = data.extruder_num
|
||||||
|
m_number_of_filaments = data.filament_colors.length
|
||||||
|
m_display_matrix = data.flush_volume_matrixs[0].slice();
|
||||||
|
m_raw_matrix = data.flush_volume_matrixs.map(function(arr) {
|
||||||
|
return arr.slice();
|
||||||
|
});
|
||||||
|
m_flush_multipiers = data.flush_multiplier.slice()
|
||||||
|
m_max_flush_volumes = data.max_flush_volumes
|
||||||
|
m_min_flush_volumes = data.min_flush_volumes
|
||||||
|
m_min_flush_multiplier = data.min_flush_multiplier
|
||||||
|
m_max_flush_multiplier = data.max_flush_multiplier
|
||||||
|
|
||||||
|
if(data.is_dark_mode == true)
|
||||||
|
document.body.classList.add('dark-mode');
|
||||||
|
|
||||||
|
updateFlushMultiplier(m_curr_extruder_id)
|
||||||
|
|
||||||
|
const selectElement = document.getElementById('extruders');
|
||||||
|
if (m_number_of_extruders > 1) {
|
||||||
|
selectElement.style.display = 'inline-block';
|
||||||
|
} else {
|
||||||
|
selectElement.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
var thead = document.querySelector("#flushTable thead tr");
|
||||||
|
var tbody = document.querySelector("#flushTable tbody");
|
||||||
|
thead.innerHTML = "";
|
||||||
|
tbody.innerHTML = "";
|
||||||
|
|
||||||
|
for (let j = 0; j < m_number_of_filaments; j++) {
|
||||||
|
if (j == 0) {
|
||||||
|
var tag = document.createElement("th")
|
||||||
|
tag.innerHTML = "<div style='font-size:12px'>from/to</div>"
|
||||||
|
thead.appendChild(tag)
|
||||||
|
}
|
||||||
|
let th = document.createElement("th");
|
||||||
|
const luminance = getLuminance(m_colours[j]);
|
||||||
|
const textColor = luminance > 0.5 ? "black" : "white";
|
||||||
|
th.innerHTML = `<div class="icon-button" style="font-size:10px;background:${m_colours[j]}; color:${textColor};">${j + 1}</div>`;
|
||||||
|
thead.appendChild(th);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < m_number_of_filaments; i++) {
|
||||||
|
let tr = document.createElement("tr");
|
||||||
|
|
||||||
|
let rowHeader = document.createElement("th");
|
||||||
|
const luminance = getLuminance(m_colours[i]);
|
||||||
|
const textColor = luminance > 0.5 ? "black" : "white";
|
||||||
|
rowHeader.innerHTML = `<div class="icon-button" style="font-size:10px; background:${m_colours[i]};color:${textColor};">${i + 1}</div>`;
|
||||||
|
tr.appendChild(rowHeader);
|
||||||
|
|
||||||
|
m_cell_inputs[i] = [];
|
||||||
|
|
||||||
|
for (let j = 0; j < m_number_of_filaments; j++) {
|
||||||
|
let td = document.createElement("td");
|
||||||
|
td.style.overflow = "hidden";
|
||||||
|
td.style.textOverflow = "ellipsis";
|
||||||
|
let displayVal = rawToDislay(m_raw_matrix[m_curr_extruder_id][m_number_of_filaments * i + j], m_flush_multipiers[m_curr_extruder_id])
|
||||||
|
displayVal = limitDisplayVal(displayVal, m_curr_extruder_id)
|
||||||
|
m_display_matrix[m_number_of_filaments*i + j] = displayVal
|
||||||
|
let readonly = (i === j);
|
||||||
|
let input = document.createElement("input");
|
||||||
|
input.className = "table-input"
|
||||||
|
input.type = "number";
|
||||||
|
input.value = readonly ? 0 : displayVal;
|
||||||
|
if (readonly) {
|
||||||
|
input.readOnly = true;
|
||||||
|
}
|
||||||
|
input.addEventListener("input", (e) => onCellInput(i, j, e));
|
||||||
|
|
||||||
|
m_cell_inputs[i][j] = input;
|
||||||
|
|
||||||
|
td.appendChild(input);
|
||||||
|
tr.appendChild(td);
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody.appendChild(tr);
|
||||||
|
}
|
||||||
|
updateWarningTexts();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCellInput(i, j, event) {
|
||||||
|
const input = event.target;
|
||||||
|
let val = parseInt(input.value, 10);
|
||||||
|
val = limitDisplayVal(val, m_curr_extruder_id);
|
||||||
|
input.value = val;
|
||||||
|
|
||||||
|
if (i !== j) {
|
||||||
|
var index = m_number_of_filaments*i+j
|
||||||
|
m_raw_matrix[m_curr_extruder_id][index] = displayToRaw(val, m_flush_multipiers[m_curr_extruder_id])
|
||||||
|
m_display_matrix[index] = val;
|
||||||
|
}
|
||||||
|
updateWarningTexts();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleExtruderSelect(extruder) {
|
||||||
|
m_curr_extruder_id = extruder == 'left' ? 0 : 1
|
||||||
|
updateTable(m_raw_matrix[m_curr_extruder_id], m_curr_extruder_id)
|
||||||
|
updateVolumeRange(m_min_flush_volumes[m_curr_extruder_id],m_max_flush_volumes[m_curr_extruder_id])
|
||||||
|
updateFlushMultiplier(m_min_flush_multiplier[m_curr_extruder_id],m_max_flush_multiplier[m_curr_extruder_id])
|
||||||
|
updateFlushMultiplier(m_curr_extruder_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMultiplierChange() {
|
||||||
|
let val = parseFloat(document.getElementById("multiplierInput").value);
|
||||||
|
if (isNaN(val)) val = 1.0;
|
||||||
|
if(val<m_min_flush_multiplier){
|
||||||
|
val = m_min_flush_multiplier
|
||||||
|
document.getElementById("multiplierInput").value = m_min_flush_multiplier;
|
||||||
|
}
|
||||||
|
else if(val>m_max_flush_multiplier){
|
||||||
|
val = m_max_flush_multiplier
|
||||||
|
document.getElementById("multiplierInput").value = m_max_flush_multiplier;
|
||||||
|
}
|
||||||
|
m_flush_multipiers[m_curr_extruder_id] = val;
|
||||||
|
for (let i = 0; i < m_number_of_filaments; i++) {
|
||||||
|
for (let j = 0; j < m_number_of_filaments; j++) {
|
||||||
|
if (i === j) continue;
|
||||||
|
var index = i * m_number_of_filaments + j;
|
||||||
|
let displayVal = rawToDislay(m_raw_matrix[m_curr_extruder_id][index] ,m_flush_multipiers[m_curr_extruder_id])
|
||||||
|
displayVal = limitDisplayVal(displayVal, m_curr_extruder_id)
|
||||||
|
m_cell_inputs[i][j].value = displayVal;
|
||||||
|
m_display_matrix[index] = displayVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateWarningTexts();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function updateWarningTexts() {
|
||||||
|
let hasException = false;
|
||||||
|
for (let i = 0; i < m_number_of_filaments; i++) {
|
||||||
|
for (let j = 0; j < m_number_of_filaments; j++) {
|
||||||
|
if (i === j) continue;
|
||||||
|
const input = m_cell_inputs[i][j];
|
||||||
|
let val = parseInt(input.value, 10);
|
||||||
|
if (isNaN(val)) val = 0;
|
||||||
|
|
||||||
|
if (val < m_min_flush_volumes[m_curr_extruder_id] || val > m_max_flush_volumes[m_curr_extruder_id]) {
|
||||||
|
input.style.color = "red";
|
||||||
|
hasException = true;
|
||||||
|
} else {
|
||||||
|
input.style.color = "black";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rangeLabel = document.getElementById("volume_range_panel");
|
||||||
|
if (hasException) {
|
||||||
|
rangeLabel.classList.remove("normal-text");
|
||||||
|
rangeLabel.classList.add("warning-text");
|
||||||
|
} else {
|
||||||
|
rangeLabel.classList.remove("warning-text");
|
||||||
|
rangeLabel.classList.add("normal-text");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -73,9 +73,9 @@ bool open_filament_group_wiki()
|
||||||
bool is_zh = wxGetApp().app_config->get("language") == "zh_CN";
|
bool is_zh = wxGetApp().app_config->get("language") == "zh_CN";
|
||||||
fs::path wiki_path;
|
fs::path wiki_path;
|
||||||
if (is_zh)
|
if (is_zh)
|
||||||
wiki_path = fs::path(resources_dir()) / "/wiki/filament_group_wiki_zh.html";
|
wiki_path = fs::path(resources_dir()) / "wiki/filament_group_wiki_zh.html";
|
||||||
else
|
else
|
||||||
wiki_path = fs::path(resources_dir()) / "/wiki/filament_group_wiki_en.html";
|
wiki_path = fs::path(resources_dir()) / "wiki/filament_group_wiki_en.html";
|
||||||
|
|
||||||
wxString wiki_path_str = wxString::FromUTF8(wiki_path.string());
|
wxString wiki_path_str = wxString::FromUTF8(wiki_path.string());
|
||||||
if (wxFileExists(wiki_path_str)) {
|
if (wxFileExists(wiki_path_str)) {
|
||||||
|
|
|
@ -1787,22 +1787,13 @@ Sidebar::Sidebar(Plater *parent)
|
||||||
extra_flush_volumes[nozzle_id] = get_min_flush_volumes(full_config, nozzle_id);
|
extra_flush_volumes[nozzle_id] = get_min_flush_volumes(full_config, nozzle_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> flush_multiplier;
|
WipingDialog dlg(static_cast<wxWindow *>(wxGetApp().mainframe),extra_flush_volumes);
|
||||||
ConfigOptionFloats *flush_multi_opt = project_config.option<ConfigOptionFloats>("flush_multiplier");
|
dlg.ShowModal();
|
||||||
if (flush_multi_opt)
|
if (dlg.GetSubmitFlag()) {
|
||||||
flush_multiplier = cast<float>(flush_multi_opt->values);
|
auto matrix = dlg.GetFlattenMatrix();
|
||||||
|
auto flush_multipliers = dlg.GetMultipliers();
|
||||||
flush_multiplier.resize(nozzle_nums, 1.0f);
|
|
||||||
|
|
||||||
WipingDialog dlg(parent, cast<float>(init_matrix), cast<float>(init_extruders), extruder_colours, extra_flush_volumes, flush_multiplier, nozzle_nums);
|
|
||||||
if (dlg.ShowModal() == wxID_OK) {
|
|
||||||
std::vector<float> matrix = dlg.get_matrix();
|
|
||||||
std::vector<float> extruders = dlg.get_extruders();
|
|
||||||
std::vector<float> flush_multipliers = dlg.get_flush_multiplier_vector();
|
|
||||||
(project_config.option<ConfigOptionFloats>("flush_volumes_matrix"))->values = std::vector<double>(matrix.begin(), matrix.end());
|
(project_config.option<ConfigOptionFloats>("flush_volumes_matrix"))->values = std::vector<double>(matrix.begin(), matrix.end());
|
||||||
(project_config.option<ConfigOptionFloats>("flush_volumes_vector"))->values = std::vector<double>(extruders.begin(), extruders.end());
|
|
||||||
(project_config.option<ConfigOptionFloats>("flush_multiplier"))->values = std::vector<double>(flush_multipliers.begin(), flush_multipliers.end());
|
(project_config.option<ConfigOptionFloats>("flush_multiplier"))->values = std::vector<double>(flush_multipliers.begin(), flush_multipliers.end());
|
||||||
|
|
||||||
wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config);
|
wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config);
|
||||||
|
|
||||||
wxGetApp().plater()->update_project_dirty_from_presets();
|
wxGetApp().plater()->update_project_dirty_from_presets();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,117 +1,33 @@
|
||||||
#ifndef _WIPE_TOWER_DIALOG_H_
|
#ifndef _WIPE_TOWER_DIALOG_H_
|
||||||
#define _WIPE_TOWER_DIALOG_H_
|
#define _WIPE_TOWER_DIALOG_H_
|
||||||
|
|
||||||
#include "GUI_Utils.hpp"
|
#include <wx/webview.h>
|
||||||
|
|
||||||
#include <wx/sizer.h>
|
|
||||||
#include <wx/spinctrl.h>
|
|
||||||
#include <wx/stattext.h>
|
|
||||||
#include <wx/textctrl.h>
|
|
||||||
#include <wx/checkbox.h>
|
|
||||||
#include <wx/msgdlg.h>
|
|
||||||
class Button;
|
|
||||||
class Label;
|
|
||||||
|
|
||||||
class WipingPanel : public wxPanel {
|
|
||||||
public:
|
|
||||||
// BBS
|
|
||||||
WipingPanel(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, size_t cur_extruder_id,
|
|
||||||
const std::vector<std::string>& extruder_colours, Button* calc_button,
|
|
||||||
const std::vector<std::vector<int>>& extra_flush_volume, const std::vector<float>& flush_multiplier, size_t nozzle_nums);
|
|
||||||
std::vector<float> read_matrix_values();
|
|
||||||
std::vector<float> read_extruders_values();
|
|
||||||
void toggle_advanced(bool user_action = false);
|
|
||||||
void create_panels(wxWindow* parent, const int num);
|
|
||||||
void calc_flushing_volumes();
|
|
||||||
void msw_rescale();
|
|
||||||
wxBoxSizer* create_calc_btn_sizer(wxWindow* parent);
|
|
||||||
|
|
||||||
float get_flush_multiplier()
|
|
||||||
{
|
|
||||||
if (m_flush_multiplier_ebox == nullptr)
|
|
||||||
return 1.f;
|
|
||||||
|
|
||||||
return wxAtof(m_flush_multiplier_ebox->GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<float> get_flush_multiplier_vector() { return m_flush_multiplier; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
void on_select_extruder(wxCommandEvent &evt);
|
|
||||||
void generate_display_matrix(); // generate display_matrix frem matrix
|
|
||||||
void back_matrix();
|
|
||||||
void update_table(); // if matrix is modified update the table
|
|
||||||
void fill_in_matrix();
|
|
||||||
bool advanced_matches_simple();
|
|
||||||
int calc_flushing_volume(const wxColour& from, const wxColour& to,int min_flush_volume);
|
|
||||||
void update_warning_texts();
|
|
||||||
|
|
||||||
std::vector<wxSpinCtrl*> m_old;
|
|
||||||
std::vector<wxSpinCtrl*> m_new;
|
|
||||||
std::vector<std::vector<wxTextCtrl*>> edit_boxes;
|
|
||||||
std::vector<wxColour> m_colours;
|
|
||||||
unsigned int m_number_of_extruders = 0;
|
|
||||||
bool m_advanced = false;
|
|
||||||
wxPanel* m_page_simple = nullptr;
|
|
||||||
wxPanel* m_page_advanced = nullptr;
|
|
||||||
wxPanel* header_line_panel = nullptr;
|
|
||||||
wxBoxSizer* m_sizer = nullptr;
|
|
||||||
wxBoxSizer* m_sizer_simple = nullptr;
|
|
||||||
wxBoxSizer* m_sizer_advanced = nullptr;
|
|
||||||
wxGridSizer* m_gridsizer_advanced = nullptr;
|
|
||||||
wxButton* m_widget_button = nullptr;
|
|
||||||
Label* m_tip_message_label = nullptr;
|
|
||||||
|
|
||||||
std::vector<wxButton *> icon_list1;
|
|
||||||
std::vector<wxButton *> icon_list2;
|
|
||||||
|
|
||||||
const std::vector<std::vector<int>> m_min_flush_volume;
|
|
||||||
const int m_max_flush_volume;
|
|
||||||
|
|
||||||
wxTextCtrl* m_flush_multiplier_ebox = nullptr;
|
|
||||||
wxStaticText* m_min_flush_label = nullptr;
|
|
||||||
|
|
||||||
std::vector<float> m_flush_multiplier;
|
|
||||||
std::vector<float> m_matrix;
|
|
||||||
std::vector<float> m_display_matrix;
|
|
||||||
size_t m_cur_extruder_id;
|
|
||||||
size_t m_nozzle_nums;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
class WipingDialog : public wxDialog
|
||||||
|
|
||||||
|
|
||||||
class WipingDialog : public Slic3r::GUI::DPIDialog
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WipingDialog(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, const std::vector<std::string>& extruder_colours,
|
using VolumeMatrix = std::vector<std::vector<double>>;
|
||||||
const std::vector<std::vector<int>>&extra_flush_volume, const std::vector<float>& flush_multiplier, size_t nozzle_nums);
|
|
||||||
std::vector<float> get_matrix() const { return m_output_matrix; }
|
|
||||||
std::vector<float> get_extruders() const { return m_output_extruders; }
|
|
||||||
wxBoxSizer* create_btn_sizer(long flags);
|
|
||||||
|
|
||||||
float get_flush_multiplier()
|
WipingDialog(wxWindow* parent,const std::vector<std::vector<int>>& extra_flush_volume, const int max_flush_volume = Slic3r::g_max_flush_volume);
|
||||||
{
|
VolumeMatrix CalcFlushingVolumes(int extruder_id);
|
||||||
if (m_panel_wiping == nullptr)
|
std::vector<double> GetFlattenMatrix()const;
|
||||||
return 1.f;
|
std::vector<double> GetMultipliers()const;
|
||||||
|
bool GetSubmitFlag() const { return m_submit_flag; }
|
||||||
return m_panel_wiping->get_flush_multiplier();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<float> get_flush_multiplier_vector() const {
|
|
||||||
if (m_panel_wiping == nullptr)
|
|
||||||
return {1.f, 1.f};
|
|
||||||
return m_panel_wiping->get_flush_multiplier_vector();
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_dpi_changed(const wxRect &suggested_rect) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WipingPanel* m_panel_wiping = nullptr;
|
int CalcFlushingVolume(const wxColour& from_, const wxColour& to_, int min_flush_volume);
|
||||||
std::vector<float> m_output_matrix;
|
wxString BuildTableObjStr();
|
||||||
std::vector<float> m_output_extruders;
|
wxString BuildTextObjStr();
|
||||||
std::unordered_map<int, Button *> m_button_list;
|
void StoreFlushData(int extruder_num, const std::vector<std::vector<double>>& flush_volume_vecs, const std::vector<double>& flush_multipliers);
|
||||||
|
|
||||||
|
wxWebView* m_webview;
|
||||||
|
std::vector<std::vector<int>> m_extra_flush_volume;
|
||||||
|
int m_max_flush_volume;
|
||||||
|
|
||||||
|
VolumeMatrix m_raw_matrixs;
|
||||||
|
std::vector<double> m_flush_multipliers;
|
||||||
|
bool m_submit_flag{ false };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _WIPE_TOWER_DIALOG_H_
|
#endif // _WIPE_TOWER_DIALOG_H_
|
Loading…
Reference in New Issue