start a new look

This commit is contained in:
Stewart Allen 2020-06-05 23:21:53 -04:00
commit d3680873fe
8 changed files with 1075 additions and 1539 deletions

View file

@ -522,7 +522,7 @@
let code = devices[API.mode.get_lower()][devicename];
setDeviceCode(code, devicename);
}
$('selected-device').innerHTML = devicename;
// $('selected-device').innerHTML = devicename;
}
// only for local filters
@ -535,6 +535,7 @@
}
function setDeviceCode(code, devicename) {
return console.log('TODO setDeviceCode');
try {
if (typeof(code) === 'string') code = js2o(code) || {};
@ -1010,6 +1011,7 @@
}
function updateCatalog(files) {
return console.log('TODO catalog render');
let table = UI.catalogList,
list = [];
table.innerHTML = '';
@ -1126,9 +1128,9 @@
layerID: $('layer-id'),
layerSpan: $('layer-span'),
layerRange: $('layer-range'),
loading: $('loading').style,
progress: $('progress').style,
prostatus: $('prostatus'),
loading: $('progress').style,
progress: $('progbar').style,
prostatus: $('progtxt'),
selection: $('selection'),
sizeX: $('size_x'),
sizeY: $('size_y'),
@ -1184,44 +1186,44 @@
gcodePre: UC.newText(LANG.dv_head_s, {title:LANG.dv_head_l, modes:GCODE, size:14, height:3}),
gcodePost: UC.newText(LANG.dv_foot_s, {title:LANG.dv_foot_l, modes:GCODE, size:14, height:3}),
mode: UC.newGroup(LANG.mo_menu, assets, {region:"left", poprow:false}),
modeTable: UC.newTableRow([
[ UI.modeFDM = UC.newButton(LANG.mo_fdmp, function() { API.mode.set('FDM',null,platform.update_size) }, {icon: icons.fdm}) ],
[ UI.modeSLA = UC.newButton(LANG.mo_slap, function() { API.mode.set('SLA',null,platform.update_size) }, {icon: icons.sla}) ],
[ UI.modeLASER = UC.newButton(LANG.mo_lazr, function() { API.mode.set('LASER',null,platform.update_size) }, {icon: icons.laser}) ],
[ UI.modeCAM = UC.newButton(LANG.mo_cncm, function() { API.mode.set('CAM',null,platform.update_size) }, {icon: icons.cam, id:"modeCAM"}) ]
]),
system: UC.newGroup(LANG.su_menu),
sysTable: UC.newTableRow([
[ UI.setupDevices = UC.newButton(LANG.su_devi, showDevices) ],
[ UI.setupTools = UC.newButton(LANG.su_tool, showTools, {modes:CAM}) ],
[ UI.setupExport = UC.newButton(LANG.su_xprt, settingsExport, {modes:ALL, expert:true}) ],
[ UI.localButton = UC.newButton(LANG.su_locl, API.show.local, {modes:FDM_CAM, expert:true}) ]
]),
wsFile: UC.newGroup(LANG.fe_menu),
wsFileTable: UC.newTableRow([
[ UI.import = UC.newButton(LANG.fn_recn, undefined, {class:"asym"}) ],
[ UI.load = UC.newButton(LANG.fn_impo, function() { API.event.import() }, {class:"asym"}) ]
]),
wsFunc: UC.newGroup(LANG.fn_menu),
wsFuncTable: UC.newTableRow([
[ UI.modeArrange = UC.newButton(LANG.fn_arra, platform.layout) ],
[ UI.modeSlice = UC.newButton(LANG.fn_slic, API.function.slice) ],
[ UI.modePreview = UC.newButton(LANG.fn_prev, API.function.print) ],
[ UI.modeExport = UC.newButton(LANG.fn_expo, API.function.export) ]
]),
workspace: UC.newGroup(LANG.ws_menu, undefined, {modes:ALL, expert:true}),
wsTable: UC.newTableRow([
[
UC.newButton(LANG.vu_sptp, SPACE.view.top),
UC.newButton(LANG.vu_home, SPACE.view.home),
],[
UI.saveButton =
UC.newButton(LANG.ws_save, API.space.save),
UC.newButton(LANG.ws_cler, API.space.clear)
]
], {modes:ALL, expert:true}),
// mode: UC.newGroup(LANG.mo_menu, assets, {region:"left", poprow:false}),
// modeTable: UC.newTableRow([
// [ UI.modeFDM = UC.newButton(LANG.mo_fdmp, function() { API.mode.set('FDM',null,platform.update_size) }, {icon: icons.fdm}) ],
// [ UI.modeSLA = UC.newButton(LANG.mo_slap, function() { API.mode.set('SLA',null,platform.update_size) }, {icon: icons.sla}) ],
// [ UI.modeLASER = UC.newButton(LANG.mo_lazr, function() { API.mode.set('LASER',null,platform.update_size) }, {icon: icons.laser}) ],
// [ UI.modeCAM = UC.newButton(LANG.mo_cncm, function() { API.mode.set('CAM',null,platform.update_size) }, {icon: icons.cnc, id:"modeCAM"}) ]
// ]),
// system: UC.newGroup(LANG.su_menu),
// sysTable: UC.newTableRow([
// [ UI.setupDevices = UC.newButton(LANG.su_devi, showDevices) ],
// [ UI.setupTools = UC.newButton(LANG.su_tool, showTools, {modes:CAM}) ],
// [ UI.setupExport = UC.newButton(LANG.su_xprt, settingsExport, {modes:ALL, expert:true}) ],
// [ UI.localButton = UC.newButton(LANG.su_locl, API.show.local, {modes:FDM_CAM, expert:true}) ]
// ]),
// wsFile: UC.newGroup(LANG.fe_menu),
// wsFileTable: UC.newTableRow([
// [ UI.import = UC.newButton(LANG.fn_recn, undefined, {class:"asym"}) ],
// [ UI.load = UC.newButton(LANG.fn_impo, function() { API.event.import() }, {class:"asym"}) ]
// ]),
// wsFunc: UC.newGroup(LANG.fn_menu),
// wsFuncTable: UC.newTableRow([
// [ UI.modeArrange = UC.newButton(LANG.fn_arra, platform.layout) ],
// [ UI.modeSlice = UC.newButton(LANG.fn_slic, API.function.slice) ],
// [ UI.modePreview = UC.newButton(LANG.fn_prev, API.function.print) ],
// [ UI.modeExport = UC.newButton(LANG.fn_expo, API.function.export) ]
// ]),
//
// workspace: UC.newGroup(LANG.ws_menu, undefined, {modes:ALL, expert:true}),
// wsTable: UC.newTableRow([
// [
// UC.newButton(LANG.vu_sptp, SPACE.view.top),
// UC.newButton(LANG.vu_home, SPACE.view.home),
// ],[
// UI.saveButton =
// UC.newButton(LANG.ws_save, API.space.save),
// UC.newButton(LANG.ws_cler, API.space.clear)
// ]
// ], {modes:ALL, expert:true}),
layout: UC.newGroup(LANG.op_menu),
expert: UC.newBoolean(LANG.op_xprt_s, booleanSave, {title:LANG.op_xprt_l}),
@ -1234,9 +1236,9 @@
units: UC.newSelect(LANG.op_unit_s, {title: LANG.op_unit_l, modes:CAM}, "units"),
// allow modules to insert new items at the bottom of the left menu
appendLeft: UC.checkpoint(),
// appendLeft: UC.checkpoint(),
settingsGroup: UC.newGroup(LANG.se_menu, control, {region:"right"}),
settingsGroup: UC.newGroup(LANG.se_menu, $('settings'), {region:"right"}),
settingsTable: UC.newTableRow([
[
UI.settingsLoad =
@ -1508,74 +1510,74 @@
}
SPACE.onEnterKey([
UI.layerSpan, function() { API.show.slices() },
UI.layerID, function() { API.show.layer(UI.layerID.value) },
UI.scaleX, selectionScale,
UI.scaleY, selectionScale,
UI.scaleZ, selectionScale,
UI.sizeX, selectionSize,
UI.sizeY, selectionSize,
UI.sizeZ, selectionSize,
UI.toolName, updateTool,
UI.toolNum, updateTool,
UI.toolFluteDiam, updateTool,
UI.toolFluteLen, updateTool,
UI.toolShaftDiam, updateTool,
UI.toolShaftLen, updateTool,
UI.toolTaperTip, updateTool,
$('rot_x'), selectionRotate,
$('rot_y'), selectionRotate,
$('rot_z'), selectionRotate
// UI.layerSpan, function() { API.show.slices() },
// UI.layerID, function() { API.show.layer(UI.layerID.value) },
// UI.scaleX, selectionScale,
// UI.scaleY, selectionScale,
// UI.scaleZ, selectionScale,
// UI.sizeX, selectionSize,
// UI.sizeY, selectionSize,
// UI.sizeZ, selectionSize,
// UI.toolName, updateTool,
// UI.toolNum, updateTool,
// UI.toolFluteDiam, updateTool,
// UI.toolFluteLen, updateTool,
// UI.toolShaftDiam, updateTool,
// UI.toolShaftLen, updateTool,
// UI.toolTaperTip, updateTool,
// $('rot_x'), selectionRotate,
// $('rot_y'), selectionRotate,
// $('rot_z'), selectionRotate
]);
UI.layerID.convert = UC.toFloat.bind(UI.layerID);
UI.layerSpan.convert = UC.toFloat.bind(UI.layerSpan);
UI.layerRange.onclick = function() {
UI.layerRange.checked = !(UI.layerRange.checked || false);
API.show.slices();
};
// UI.layerID.convert = UC.toFloat.bind(UI.layerID);
// UI.layerSpan.convert = UC.toFloat.bind(UI.layerSpan);
// UI.layerRange.onclick = function() {
// UI.layerRange.checked = !(UI.layerRange.checked || false);
// API.show.slices();
// };
//
// $('layer-toggle').onclick = function(ev) {
// let ls = UI.layers.style;
// ls.display = ls.display !== 'block' ? 'block' : 'none';
// UI.layers.style.left = ev.target.getBoundingClientRect().left + 'px';
// };
$('layer-toggle').onclick = function(ev) {
let ls = UI.layers.style;
ls.display = ls.display !== 'block' ? 'block' : 'none';
UI.layers.style.left = ev.target.getBoundingClientRect().left + 'px';
};
// UI.modelOpacity.onchange = UI.modelOpacity.onclick = function(ev) {
// API.widgets.opacity(parseInt(UI.modelOpacity.value)/100);
// };
//
// UI.layerSlider.ondblclick = function() {
// UI.layerRange.checked = !UI.layerRange.checked;
// API.show.slices();
// };
//
// UI.layerSlider.onmousedown = function(ev) {
// if (ev.shiftKey) UI.layerRange.checked = !UI.layerRange.checked;
// };
//
// UI.layerSlider.onclick = function() {
// API.show.layer(UI.layerSlider.value);
// };
//
// UI.layerSlider.onmousemove = UI.layerSlider.onchange = function() {
// API.show.layer(UI.layerSlider.value);
// };
//
// UI.layerSlider.onmouseup = function() { API.focus() };
//
// UI.import.setAttribute("import","1");
// UI.import.onclick = function() {
// UC.hidePoppers();
// API.dialog.show("catalog");
// };
//
// $('cache-close').onclick = API.dialog.hide;
//
// UI.toolMetric.onclick = updateTool;
// UI.toolType.onchange = updateTool;
UI.modelOpacity.onchange = UI.modelOpacity.onclick = function(ev) {
API.widgets.opacity(parseInt(UI.modelOpacity.value)/100);
};
UI.layerSlider.ondblclick = function() {
UI.layerRange.checked = !UI.layerRange.checked;
API.show.slices();
};
UI.layerSlider.onmousedown = function(ev) {
if (ev.shiftKey) UI.layerRange.checked = !UI.layerRange.checked;
};
UI.layerSlider.onclick = function() {
API.show.layer(UI.layerSlider.value);
};
UI.layerSlider.onmousemove = UI.layerSlider.onchange = function() {
API.show.layer(UI.layerSlider.value);
};
UI.layerSlider.onmouseup = function() { API.focus() };
UI.import.setAttribute("import","1");
UI.import.onclick = function() {
UC.hidePoppers();
API.dialog.show("catalog");
};
$('cache-close').onclick = API.dialog.hide;
UI.toolMetric.onclick = updateTool;
UI.toolType.onchange = updateTool;
$('apphelp').onclick = API.help.show;
$('app-name').onclick = API.help.show;
SPACE.platform.setSize(
settings().device.bedWidth,
@ -1583,7 +1585,7 @@
settings().device.bedHeight
);
UI.selection.classList.add('compact');
// UI.selection.classList.add('compact');
if (dark) {
SPACE.platform.setGrid(25, 5, 0x999999, 0x333333);
@ -1765,7 +1767,7 @@
API.dialog.update();
// show version on startup
API.show.alert(`${LANG.version} ${KIRI.version}`);
$('app-vers').innerHTML = KIRI.version;
if (!SETUP.s) console.log(`kiri | init main | ${KIRI.version}`);

View file

@ -39,7 +39,7 @@
newWidget = kiri.newWidget,
// ---------------
UI = {},
UC = MOTO.ui.prefix('kiri').inputAction(updateSettings).hideAction(updateDialogLeft),
UC = KIRI.ui.prefix('kiri').inputAction(updateSettings).hideAction(updateDialogLeft),
MODE = MODES.FDM,
onEvent = {},
currentPrint = null,
@ -502,6 +502,7 @@
}
function updateSliderMax(set) {
return console.log('TODO updateSliderMax');
let max = 0;
if (viewMode === VIEWS.PREVIEW && currentPrint) {
max = currentPrint.getLayerCount();
@ -558,8 +559,8 @@
layer = bound(layer, 0, API.var.layer_max);
UI.layerID.value = layer;
UI.layerSlider.value = layer;
// UI.layerID.value = layer;
// UI.layerSlider.value = layer;
let j,
slice,
@ -849,12 +850,12 @@
});
if (bounds.min.x === Infinity) {
if (selectedMeshes.length === 0) {
UI.sizeX.value = 0;
UI.sizeY.value = 0;
UI.sizeZ.value = 0;
UI.scaleX.value = 1;
UI.scaleY.value = 1;
UI.scaleZ.value = 1;
// UI.sizeX.value = 0;
// UI.sizeY.value = 0;
// UI.sizeZ.value = 0;
// UI.scaleX.value = 1;
// UI.scaleY.value = 1;
// UI.scaleZ.value = 1;
}
return;
}
@ -862,17 +863,17 @@
dy = bounds.max.y - bounds.min.y,
dz = bounds.max.z - bounds.min.z,
scale = unitScale();
UI.sizeX.value = UI.sizeX.was = UTIL.round(dx/scale,2);
UI.sizeY.value = UI.sizeY.was = UTIL.round(dy/scale,2);
UI.sizeZ.value = UI.sizeZ.was = UTIL.round(dz/scale,2);
UI.scaleX.value = UI.scaleX.was = track.scale.x;
UI.scaleY.value = UI.scaleY.was = track.scale.y;
UI.scaleZ.value = UI.scaleZ.was = track.scale.z;
// UI.sizeX.value = UI.sizeX.was = UTIL.round(dx/scale,2);
// UI.sizeY.value = UI.sizeY.was = UTIL.round(dy/scale,2);
// UI.sizeZ.value = UI.sizeZ.was = UTIL.round(dz/scale,2);
// UI.scaleX.value = UI.scaleX.was = track.scale.x;
// UI.scaleY.value = UI.scaleY.was = track.scale.y;
// UI.scaleZ.value = UI.scaleZ.was = track.scale.z;
}
function setOpacity(value) {
forAllWidgets(function (w) { w.setOpacity(value) });
UI.modelOpacity.value = value * 100;
// UI.modelOpacity.value = value * 100;
SPACE.update();
}
@ -1018,8 +1019,8 @@
}
function platformUpdateSelected() {
UI.selection.style.display = platform.selected_count() ? 'inline' : 'none';
$('ext-sel').style.display = (MODE === MODES.FDM) ? 'inline-block' : 'none';
// UI.selection.style.display = platform.selected_count() ? 'inline' : 'none';
// $('ext-sel').style.display = (MODE === MODES.FDM) ? 'inline-block' : 'none';
let extruders = settings.device.extruders;
if (extruders) {
for (let i=0; i<extruders.length; i++) {
@ -1225,7 +1226,7 @@
camTopZ = topZ;
// create/inject cam stock if stock size other than default
if (MODE === MODES.CAM && stockSet && WIDGETS.length) {
UI.stock.style.display = offset ? 'inline-block' : 'none';
// UI.stock.style.display = offset ? 'inline-block' : 'none';
let csx = sd.camStockX * scale;
let csy = sd.camStockY * scale;
let csz = sd.camStockZ * scale;
@ -1253,9 +1254,9 @@
csz += max.z - min.z;
csox = min.x + ((max.x - min.x) / 2);
csoy = min.y + ((max.y - min.y) / 2);
$('stock-width').innerText = (csx/scale).toFixed(2);
$('stock-depth').innerText = (csy/scale).toFixed(2);
$('stock-height').innerText = (csz/scale).toFixed(2);
// $('stock-width').innerText = (csx/scale).toFixed(2);
// $('stock-depth').innerText = (csy/scale).toFixed(2);
// $('stock-height').innerText = (csz/scale).toFixed(2);
}
if (!camStock) {
let geo = new THREE.BoxGeometry(1, 1, 1);
@ -1635,6 +1636,7 @@
}
function showDialog(which, force) {
return console.log('TODO showDialog');
if (UC.isPopped()) {
UC.hidePop();
return;
@ -1694,9 +1696,9 @@
settings.devproc[currentDeviceName()] = name;
// update selection display
$('selected-mode').innerHTML = API.mode.get();
$('selected-device').innerHTML = API.device.get();
$('selected-process').innerHTML = name;
// $('selected-mode').innerHTML = API.mode.get();
// $('selected-device').innerHTML = API.device.get();
// $('selected-process').innerHTML = name;
// FDM process settings overridden by device
if (mode == "FDM") {
@ -1765,6 +1767,7 @@
}
function updateDialogLeft() {
return console.log('TODO updateDialogLeft');
let left = UI.ctrlLeft.getBoundingClientRect();
let right = UI.ctrlRight.getBoundingClientRect();
UI.catalog.style.left = (left.width + 5) + 'px';
@ -1828,14 +1831,15 @@
}
function setFocus(el) {
el = [ el || UI.load, UI.import, UI.ctrlLeft, UI.container, UI.assets, UI.control, UI.modeFDM, UI.reverseZoom, UI.modelOpacity, DOC.body ];
for (let es, i=0; i<el.length; i++) {
es = el[i];
es.focus();
if (DOC.activeElement === es) {
break;
}
}
console.log('TODO setFocus')
// el = [ el || UI.load, UI.import, UI.ctrlLeft, UI.container, UI.assets, UI.control, UI.modeFDM, UI.reverseZoom, UI.modelOpacity, DOC.body ];
// for (let es, i=0; i<el.length; i++) {
// es = el[i];
// es.focus();
// if (DOC.activeElement === es) {
// break;
// }
// }
}
function setViewMode(mode) {
@ -1868,6 +1872,7 @@
}
function showModeActive(el) {
return console.log('TODO showModeActive');
[ UI.modeArrange, UI.modeSlice, UI.modePreview, UI.modeExport ].forEach(function(b) {
if (b === el) {
b.classList.add('buton');
@ -1878,7 +1883,7 @@
}
function showLayerView(bool) {
UI.layerView.style.display = bool ? 'flex' : 'none';
// UI.layerView.style.display = bool ? 'flex' : 'none';
}
function setExpert(bool) {
@ -1923,14 +1928,14 @@
API.conf.save();
clearWidgetCache();
SPACE.update();
UI.modeFDM.setAttribute('class', MODE === MODES.FDM ? 'buton' : '');
UI.modeSLA.setAttribute('class', MODE === MODES.SLA ? 'buton' : '');
UI.modeCAM.setAttribute('class', MODE === MODES.CAM ? 'buton' : '');
UI.modeLASER.setAttribute('class', MODE === MODES.LASER ? 'buton' : '');
UI.mode.style.display = lock ? 'none' : '';
UI.modeTable.style.display = lock ? 'none' : '';
UI.modelOpacity.style.display = MODE === MODES.SLA ? 'none' : '';
UI.modePreview.style.display = MODE === MODES.SLA ? 'none' : '';
// UI.modeFDM.setAttribute('class', MODE === MODES.FDM ? 'buton' : '');
// UI.modeSLA.setAttribute('class', MODE === MODES.SLA ? 'buton' : '');
// UI.modeCAM.setAttribute('class', MODE === MODES.CAM ? 'buton' : '');
// UI.modeLASER.setAttribute('class', MODE === MODES.LASER ? 'buton' : '');
// UI.mode.style.display = lock ? 'none' : '';
// UI.modeTable.style.display = lock ? 'none' : '';
// UI.modelOpacity.style.display = MODE === MODES.SLA ? 'none' : '';
// UI.modePreview.style.display = MODE === MODES.SLA ? 'none' : '';
if (camStock) {
camStock.material.visible = settings.mode === 'CAM';
}
@ -1950,8 +1955,9 @@
}
function setControlsVisible(show) {
UI.ctrlLeft.style.display = show ? 'block' : 'none';
UI.ctrlRight.style.display = show ? 'block' : 'none';
console.log('TODO setControlsVisible');
// UI.ctrlLeft.style.display = show ? 'block' : 'none';
// UI.ctrlRight.style.display = show ? 'block' : 'none';
}
// prevent safari from exiting full screen mode

579
src/kiri/ui.js Normal file
View file

@ -0,0 +1,579 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
(function() {
if (kiri.ui) return;
let SELF = self,
KIRI = self.kiri,
lastRegion = null,
lastGroup = null,
lastDiv = null,
addTo = null,
hideAction = null,
inputAction = null,
groups = {},
groupShow = {},
groupName = undefined,
hideable = {},
hasModes = [],
isExpert = [],
letMode = null,
letExpert = false,
SDB = moto.KV,
DOC = SELF.document,
prefix = "tab",
NOMODE = "nomode",
exitimer = undefined;
SELF.$ = (SELF.$ || function (id) { return DOC.getElementById(id) } );
KIRI.ui = {
prefix: function(pre) { prefix = pre; return kiri.ui },
hideAction: function(fn) { hideAction = fn; return kiri.ui },
inputAction: function(fn) { inputAction = fn; return kiri.ui },
setMode: setMode,
setExpert: setExpert,
bound: bound,
toInt: toInt,
toFloat: toFloat,
hidePop: hidePop,
isPopped: isPopped,
newText: newTextArea,
newLabel: newLabel,
newRange: newRange,
newInput: newInputField,
newButton: newButton,
newBoolean: newBooleanField,
newSelect: newSelect,
newTable: newTables,
newTableRow: newTableRow,
newRow: newRow,
newBlank: newBlank,
newGroup: newGroup,
setGroup: setGroup,
hidePoppers: hidePoppers,
checkpoint,
restore
};
function setMode(mode) {
// $('control-left').classList.add('compact');
// $('control-right').classList.add('compact');
Object.keys(groupShow).forEach(group => {
updateGroupShow(group);
});
letMode = mode;
hasModes.forEach(function(div) {
div.setMode(div._group && !groupShow[div._group] ? NOMODE : mode);
});
}
function setExpert(bool) {
letExpert = bool;
setMode(letMode);
}
function checkpoint() {
return { addTo, lastDiv, lastGroup, lastRegion, groupName };
}
function restore(opt) {
if (opt) {
addTo = opt.addTo;
lastDiv = opt.lastDiv;
lastGroup = opt.lastGroup;
lastRegion = opt.lastRegion;
groupName = opt.groupName;
}
}
// at present only used by the layers popup menu
function setGroup(div) {
addTo = lastDiv = div;
groupName = undefined;
lastGroup = [];
return div;
}
function newGroup(label, div, options) {
lastDiv = div || lastDiv;
return addCollapsableGroup(label, lastDiv, options);
}
function addCollapsableGroup(label, div, options) {
let opt = options || {};
let group = opt.group || label;
lastRegion = opt.region || lastRegion;
hideable[group] = opt.nocompact === true ? false : true;
let row = DOC.createElement('div'),
a = DOC.createElement('a'),
dbkey = `beta-${prefix}-show-${group}`,
popper = !opt.nocompact;
if (popper) {
let pop = DOC.createElement('div');
pop.classList.add('popper');
if (lastRegion) pop.classList.add(lastRegion);
if (opt.poprow) pop.classList.add('poprow')
row.appendChild(pop);
addTo = pop;
} else {
addTo = lastDiv;
}
div.appendChild(row);
row.setAttribute("class", "grouphead noselect");
row.appendChild(a);
a.appendChild(DOC.createTextNode(label));
addModeControls(row, opt);
lastGroup = groups[group] = [];
lastGroup.key = dbkey;
groupName = group;
groupShow[group] = popper ? SDB[dbkey] === 'true' : SDB[dbkey] !== 'false';
row.onclick = function(ev) {
if (ev.target !== a && ev.target !== row) {
return;
}
toggleGroup(group, dbkey);
};
if (popper) {
row.onmouseenter = function(ev) {
if (ev.target !== a && ev.target !== row) {
return;
}
clearTimeout(exitimer);
showGroup(group);
};
row.onmouseleave = function(ev) {
if (ev.target !== a && ev.target !== row) {
return;
}
clearTimeout(exitimer);
exitimer = setTimeout(showGroup, 1000);
};
addTo._group = group;
addModeControls(addTo, opt);
lastGroup.push(addTo);
}
return row;
}
function hidePoppers() {
showGroup(undefined);
}
function showGroup(groupname) {
Object.keys(groups).forEach(name => {
let group = groups[name];
groupShow[name] = SDB[group.key] = (groupname === name);
updateGroupShow(name);
});
}
function toggleGroup(groupname, dbkey) {
let show = SDB[dbkey] === 'false';
groupShow[groupname] = hideable[groupname] ? SDB[dbkey] = show : true;
updateGroupShow(groupname);
}
function updateGroupShow(groupname) {
let show = groupShow[groupname] || !hideable[groupname];
let group = groups[groupname];
group.forEach(div => {
if (show) div.setMode(letMode);
else div.setMode(NOMODE);
});
}
function toInt() {
let nv = this.value !== '' ? parseInt(this.value) : null;
if (isNaN(nv)) nv = 0;
if (nv !== null && this.bound) nv = this.bound(nv);
this.value = nv;
return nv;
}
function toFloat() {
let nv = this.value !== '' ? parseFloat(this.value) : null;
if (nv !== null && this.bound) nv = this.bound(nv);
this.value = nv;
return nv;
}
function bound(low,high) {
return function(v) {
if (isNaN(v)) return low;
return v < low ? low : v > high ? high : v;
};
}
function raw() {
return this.value !== '' ? this.value : null;
}
function newLabel(text) {
let label = DOC.createElement('label');
label.appendChild(DOC.createTextNode(text));
label.setAttribute("class", "noselect");
return label;
}
function addId(el, options) {
if (options && options.id) {
el.setAttribute("id", options.id);
}
}
function addModeControls(el, options) {
options = options || {};
el.__show = true;
el.__modeSave = null;
el.showMe = function() {
if (el.__show) return;
el.style.display = el.__modeSave;
el.__show = true;
el.__modeSave = null;
};
el.hideMe = function() {
if (!el.__show) return;
el.__show = false;
el.__modeSave = el.style.display;
el.style.display = 'none';
};
el.setVisible = function(show) {
if (show) el.showMe();
else el.hideMe();
};
el.setMode = function(mode) {
let show = options.expert === undefined || (options.expert === letExpert);
el.setVisible(el.hasMode(mode) && show);
}
el.hasMode = function(mode) {
if (mode === NOMODE) return false;
if (!el.modes) return true;
return el.modes.contains(mode);
}
if (options.modes) {
el.modes = options.modes;
hasModes.push(el);
}
}
function newDiv(options) {
let div = DOC.createElement('div');
addModeControls(div, options);
addTo.appendChild(div);
lastGroup.push(div);
div._group = groupName;
return div;
}
let lastPop = null;
let savePop = null;
function hidePop() {
if (lastPop) {
lastPop.style.display = "none";
}
if (savePop) {
savePop();
savePop = null;
}
lastPop = null;
}
function isPopped() {
return lastPop !== null;
}
function newTextArea(label, options) {
let opt = options || {},
row = newDiv(options),
btn = DOC.createElement("button"),
box = DOC.createElement("div"),
pop = DOC.createElement("div"),
lbl = DOC.createElement("label"),
txt = DOC.createElement("textarea");
pop.setAttribute("class", "poptext flow-col");
box.setAttribute("style", "position: relative");
box.appendChild(pop);
pop.appendChild(lbl);
pop.appendChild(txt);
lbl.appendChild(DOC.createTextNode(label));
txt.setAttribute("cols", 40);
txt.setAttribute("rows", 20);
txt.setAttribute("wrap", "off");
btn.appendChild(DOC.createTextNode("edit"));
btn.onclick = function(ev) {
ev.stopPropagation();
if (ev.target === txt) {
// drop clicks on TextArea
ev.target.focus();
} else {
// first time, button click / show
btn.parentNode.appendChild(box);
btn.parentNode.onclick = btn.onclick;
txt.scrollTop = 0;
txt.scrollLeft = 0;
txt.selectionEnd = 0;
let rows = txt.value.split('\n');
let cols = 0;
rows.forEach(row => {
cols = Math.max(cols, row.length);
});
txt.setAttribute("cols", Math.max(30, cols + 1));
txt.setAttribute("rows", Math.max(10, rows.length + 1));
let showing = pop === lastPop;
hidePop();
if (!showing) {
savePop = inputAction;
pop.style.display = "flex";
lastPop = pop;
txt.focus();
} else {
inputAction();
}
}
};
addModeControls(btn, opt);
addId(btn, opt);
row.appendChild(newLabel(label));
row.appendChild(btn);
row.setAttribute("class", "flow-row");
if (opt.title) row.setAttribute("title", options.title);
btn.setVisible = row.setVisible;
return txt;
}
function newInputField(label, options) {
let opt = options || {},
row = newDiv(opt),
hide = opt && opt.hide,
size = opt ? opt.size || 5 : 5,
height = opt ? opt.height : 0,
ip = height > 1 ? DOC.createElement('textarea') : DOC.createElement('input'),
action = opt.action || inputAction;
row.appendChild(newLabel(label));
row.appendChild(ip);
row.setAttribute("class", "flow-row");
if (height > 1) {
ip.setAttribute("cols", size);
ip.setAttribute("rows", height);
ip.setAttribute("wrap", "off");
} else {
if (Number.isInteger(size)) {
ip.setAttribute("size", size);
} else {
ip.setAttribute("style", `width:${size}`);
}
}
ip.setAttribute("type", "text");
row.style.display = hide ? 'none' : '';
if (opt) {
if (opt.disabled) ip.setAttribute("disabled", "true");
if (opt.title) row.setAttribute("title", opt.title);
if (opt.convert) ip.convert = opt.convert.bind(ip);
if (opt.bound) ip.bound = opt.bound;
if (opt.action) action = opt.action;
}
ip.addEventListener('focus', function(event) {
hidePop();
});
if (action) {
ip.addEventListener('keydown', function(event) {
let key = event.key;
if (
opt.text ||
(key >= '0' && key <= '9') ||
key === '.' ||
key === '-' ||
key === 'Backspace' ||
key === 'Delete' ||
key === 'ArrowLeft' ||
key === 'ArrowRight' ||
key === 'Tab' ||
event.metaKey ||
event.ctrlKey ||
(key === ',' && options.comma)
) {
return;
}
event.preventDefault();
event.stopPropagation();
});
ip.addEventListener('keyup', function(event) {
if (event.keyCode === 13) {
// action(event);
ip.blur();
}
});
ip.addEventListener('blur', function(event) {
action(event);
});
}
if (!ip.convert) ip.convert = raw.bind(ip);
ip.setVisible = row.setVisible;
return ip;
}
function newRange(label, options) {
let row = newDiv(options),
ip = DOC.createElement('input'),
hide = options && options.hide,
action = inputAction;
if (label) row.appendChild(newLabel(label));
row.appendChild(ip);
row.setAttribute("class", "flow-row");
ip.setAttribute("type", "range");
ip.setAttribute("min", (options && options.min ? options.min : 0));
ip.setAttribute("max", (options && options.max ? options.max : 100));
ip.setAttribute("value", 0);
row.style.display = hide ? 'none' : '';
if (options) {
if (options.title) {
ip.setAttribute("title", options.title);
row.setAttribute("title", options.title);
}
if (options.action) action = options.action;
}
ip.setVisible = row.setVisible;
return ip;
}
function newSelect(label, options, source) {
let row = newDiv(options),
ip = DOC.createElement('select'),
hide = options && options.hide,
action = inputAction;
row.appendChild(newLabel(label));
row.appendChild(ip);
row.setAttribute("source", source || "tools");
row.setAttribute("class", "flow-row");
row.style.display = hide ? 'none' : '';
if (options) {
if (options.convert) ip.convert = options.convert.bind(ip);
if (options.disabled) ip.setAttribute("disabled", "true");
if (options.title) row.setAttribute("title", options.title);
if (options.action) action = options.action;
}
ip.onchange = function() { action() };
ip.setVisible = row.setVisible;
return ip;
}
function newBooleanField(label, action, options) {
let row = newDiv(options),
ip = DOC.createElement('input'),
hide = options && options.hide;
if (label) {
row.appendChild(newLabel(label));
}
row.appendChild(ip);
row.setAttribute("class", "flow-row");
row.style.display = hide ? 'none' : '';
ip.setAttribute("type", "checkbox");
ip.checked = false;
if (options) {
if (options.disabled) ip.setAttribute("disabled", "true");
if (options.title) {
ip.setAttribute("title", options.title);
row.setAttribute("title", options.title);
}
}
if (action) ip.onclick = function() { action() };
ip.setVisible = row.setVisible;
return ip;
}
function newBlank(options) {
let row = newDiv(options),
hide = options && options.hide;
row.setAttribute("class", "flow-row");
row.style.display = hide ? 'none' : '';
ip.setVisible = row.setVisible;
return ip;
}
function newButton(label, action, options) {
let b = DOC.createElement('button'),
t = DOC.createTextNode(label);
b.onclick = function() {
hidePoppers();
if (action) action();
};
if (options) {
if (options.class) b.classList.add(options.class);
if (options.icon) {
let d = DOC.createElement('div');
d.innerHTML = options.icon;
b.appendChild(d);
}
}
b.appendChild(t);
addModeControls(b, options);
addId(b, options);
return b;
}
function newTableRow(arrayOfArrays, options) {
return newRow(newTables(arrayOfArrays), options);
}
function newTables(arrayOfArrays) {
let array = [];
for (let i=0; i<arrayOfArrays.length; i++) {
array.push(newRowTable(arrayOfArrays[i]));
}
return array;
}
function newRowTable(array) {
let div = newDiv();
div.setAttribute("class", "tablerow");
array.forEach(function(c) {
div.appendChild(c);
});
return div;
}
function newRow(children, options) {
let row = addCollapsableElement((options && options.noadd) ? null : addTo);
if (children) children.forEach(function (c) { row.appendChild(c) });
addModeControls(row, options);
return row;
}
function addCollapsableElement(parent) {
let row = newDiv();
if (parent) parent.appendChild(row);
if (lastGroup) lastGroup.push(row);
return row;
}
})();