203 lines
6.8 KiB
JavaScript
203 lines
6.8 KiB
JavaScript
/* globals $ */
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class LayersPanel {
|
|
/**
|
|
* @param {PlainObject} svgCanvas svgCanvas
|
|
* @param {PlainObject} uiStrings uiStrings
|
|
* @param {GenericCallBack} updateContextPanel updateContextPanel
|
|
*/
|
|
constructor (svgCanvas, uiStrings, updateContextPanel) {
|
|
this.svgCanvas = svgCanvas;
|
|
this.uiStrings = uiStrings;
|
|
this.updateContextPanel = updateContextPanel;
|
|
}
|
|
/**
|
|
* @returns {void}
|
|
*/
|
|
addEvents () {
|
|
document.getElementById('layer_new').addEventListener('click', this.newLayer.bind(this));
|
|
document.getElementById('layer_delete').addEventListener('click', this.deleteLayer.bind(this));
|
|
document.getElementById('layer_up').addEventListener('click', () => this.moveLayer.bind(this)(-1));
|
|
document.getElementById('layer_down').addEventListener('click', () => this.moveLayer.bind(this)(1));
|
|
document.getElementById('layer_rename').addEventListener('click', this.layerRename.bind(this));
|
|
}
|
|
/**
|
|
* @returns {void}
|
|
*/
|
|
async newLayer () {
|
|
let uniqName;
|
|
let i = this.svgCanvas.getCurrentDrawing().getNumLayers();
|
|
do {
|
|
uniqName = this.uiStrings.layers.layer + ' ' + (++i);
|
|
} while (this.svgCanvas.getCurrentDrawing().hasLayer(uniqName));
|
|
|
|
const newName = await $.prompt(this.uiStrings.notification.enterUniqueLayerName, uniqName);
|
|
if (!newName) { return; }
|
|
if (this.svgCanvas.getCurrentDrawing().hasLayer(newName)) {
|
|
/* await */ $.alert(this.uiStrings.notification.dupeLayerName);
|
|
return;
|
|
}
|
|
this.svgCanvas.createLayer(newName);
|
|
this.updateContextPanel();
|
|
this.populateLayers();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
deleteLayer () {
|
|
if (this.svgCanvas.deleteCurrentLayer()) {
|
|
this.updateContextPanel();
|
|
this.populateLayers();
|
|
// This matches what this.svgCanvas does
|
|
// TODO: make this behavior less brittle (svg-editor should get which
|
|
// layer is selected from the canvas and then select that one in the UI)
|
|
$('#layerlist tr.layer').removeClass('layersel');
|
|
$('#layerlist tr.layer:first').addClass('layersel');
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @returns {Promise<void>}
|
|
*/
|
|
async cloneLayer () {
|
|
const name = this.svgCanvas.getCurrentDrawing().getCurrentLayerName() + ' copy';
|
|
|
|
const newName = await $.prompt(this.uiStrings.notification.enterUniqueLayerName, name);
|
|
if (!newName) { return; }
|
|
if (this.svgCanvas.getCurrentDrawing().hasLayer(newName)) {
|
|
/* await */ $.alert(this.uiStrings.notification.dupeLayerName);
|
|
return;
|
|
}
|
|
this.svgCanvas.cloneLayer(newName);
|
|
this.updateContextPanel();
|
|
this.populateLayers();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
mergeLayer () {
|
|
if ($('#layerlist tr.layersel').index() === this.svgCanvas.getCurrentDrawing().getNumLayers() - 1) {
|
|
return;
|
|
}
|
|
this.svgCanvas.mergeLayer();
|
|
this.updateContextPanel();
|
|
this.populateLayers();
|
|
}
|
|
|
|
/**
|
|
* @param {Integer} pos
|
|
* @returns {void}
|
|
*/
|
|
moveLayer (pos) {
|
|
const total = this.svgCanvas.getCurrentDrawing().getNumLayers();
|
|
|
|
let curIndex = $('#layerlist tr.layersel').index();
|
|
if (curIndex > 0 || curIndex < total - 1) {
|
|
curIndex += pos;
|
|
this.svgCanvas.setCurrentLayerPosition(total - curIndex - 1);
|
|
this.populateLayers();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @returns {void}
|
|
*/
|
|
async layerRename () {
|
|
// const curIndex = $('#layerlist tr.layersel').prevAll().length; // Currently unused
|
|
const oldName = $('#layerlist tr.layersel td.layername').text();
|
|
const newName = await $.prompt(this.uiStrings.notification.enterNewLayerName, '');
|
|
if (!newName) { return; }
|
|
if (oldName === newName || this.svgCanvas.getCurrentDrawing().hasLayer(newName)) {
|
|
/* await */ $.alert(this.uiStrings.notification.layerHasThatName);
|
|
return;
|
|
}
|
|
this.svgCanvas.renameCurrentLayer(newName);
|
|
this.populateLayers();
|
|
}
|
|
|
|
/**
|
|
* This function highlights the layer passed in (by fading out the other layers).
|
|
* If no layer is passed in, this function restores the other layers.
|
|
* @param {string} [layerNameToHighlight]
|
|
* @returns {void}
|
|
*/
|
|
toggleHighlightLayer (layerNameToHighlight) {
|
|
let i;
|
|
const curNames = [], numLayers = this.svgCanvas.getCurrentDrawing().getNumLayers();
|
|
for (i = 0; i < numLayers; i++) {
|
|
curNames[i] = this.svgCanvas.getCurrentDrawing().getLayerName(i);
|
|
}
|
|
|
|
if (layerNameToHighlight) {
|
|
curNames.forEach((curName) => {
|
|
if (curName !== layerNameToHighlight) {
|
|
this.svgCanvas.getCurrentDrawing().setLayerOpacity(curName, 0.5);
|
|
}
|
|
});
|
|
} else {
|
|
curNames.forEach((curName) => {
|
|
this.svgCanvas.getCurrentDrawing().setLayerOpacity(curName, 1.0);
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @returns {void}
|
|
*/
|
|
populateLayers () {
|
|
this.svgCanvas.clearSelection();
|
|
const layerlist = $('#layerlist tbody').empty();
|
|
const selLayerNames = $('#selLayerNames').empty();
|
|
const drawing = this.svgCanvas.getCurrentDrawing();
|
|
const currentLayerName = drawing.getCurrentLayerName();
|
|
let layer = this.svgCanvas.getCurrentDrawing().getNumLayers();
|
|
// we get the layers in the reverse z-order (the layer rendered on top is listed first)
|
|
while (layer--) {
|
|
const name = drawing.getLayerName(layer);
|
|
const layerTr = $('<tr class="layer">').toggleClass('layersel', name === currentLayerName);
|
|
const layerVis = $('<td class="layervis">').toggleClass('layerinvis', !drawing.getLayerVisibility(name));
|
|
const layerName = $('<td class="layername">' + name + '</td>');
|
|
layerlist.append(layerTr.append(layerVis, layerName));
|
|
selLayerNames.append('<option value="' + name + '">' + name + '</option>');
|
|
}
|
|
// handle selection of layer
|
|
$('#layerlist td.layername')
|
|
.mouseup((evt) => {
|
|
$('#layerlist tr.layer').removeClass('layersel');
|
|
$(evt.currentTarget.parentNode).addClass('layersel');
|
|
this.svgCanvas.setCurrentLayer(evt.currentTarget.textContent);
|
|
evt.preventDefault();
|
|
})
|
|
.mouseover((evt) => {
|
|
this.toggleHighlightLayer(this.svgCanvas, evt.currentTarget.textContent);
|
|
})
|
|
.mouseout(() => {
|
|
this.toggleHighlightLayer(this.svgCanvas);
|
|
});
|
|
$('#layerlist td.layervis').click((evt) => {
|
|
const row = $(evt.currentTarget.parentNode).prevAll().length;
|
|
const name = $('#layerlist tr.layer:eq(' + row + ') td.layername').text();
|
|
const vis = $(evt.currentTarget).hasClass('layerinvis');
|
|
this.svgCanvas.setLayerVisibility(name, vis);
|
|
$(evt.currentTarget).toggleClass('layerinvis');
|
|
});
|
|
|
|
// if there were too few rows, let's add a few to make it not so lonely
|
|
let num = 5 - $('#layerlist tr.layer').size();
|
|
while (num-- > 0) {
|
|
// TODO: there must a better way to do this
|
|
layerlist.append('<tr><td style="color:white">_</td><td/></tr>');
|
|
}
|
|
}
|
|
}
|
|
|
|
export default LayersPanel;
|