import { unByKey } from 'ol/Observable'
import Bar from 'ol-ext/control/Bar'
import Toggle from 'ol-ext/control/Toggle'
import TextButton from 'ol-ext/control/TextButton'
import { getButtonHtml } from './ControlBarUtils'
// écouteurs d'event sur les suppressions de calques de core
const coreLayerEvents = []
// change la visibilité d'un calque
const toggleLayerVisibility = async function (evt) {
if (evt.target.get('layerid') === '__allbackground') {
this.updating = true
this.viewer.commonLayer.getLayers('background').forEach((layer) => layer.setVisible(evt.active))
this.updating = false
setBackGroundActiveState.call(this, evt.target)
return
}
const layer = this.viewer.commonLayer.getLayer(evt.target.get('layerid'), evt.target.get('type'))
layer.setVisible(evt.active)
}
// calcul l'état du bouton "background"
const setBackGroundActiveState = function (ctrl) {
// on ne change pas l'état du bouton si c'est a cause de toggleLayerVisibility
if (this.updating) { return }
const active = this.viewer.commonLayer.getLayers('background').some((layer) => layer.getVisible())
ctrl.setActive(active)
}
const onToggle = function (active) {
this.toggle.toggle()
}
/**
*
* @param {Object} options
* @param {Object} options.viewer Instance de kmapviewer
* @param {string} options.className classe de la barre de layers
* @param {Element|string} html contenu du bouton
* @param {string} icon icone si html non saisie (utilisé comme <i class='icon'/>)
* @returns {object} ControlBarLayerBar
*/
const ControlBarLayerVisibility = function (options) {
options = options || {}
this.viewer = options.viewer || null
this.className = (options.className || '') + ' kmapv-layer-visibility-bar'
this.updating = false
this.toggle = new Toggle({
name: 'kmapv-layer-visibility-bar',
html: options.html ? options.html : (options.icon ? `<i class="${options.icon}"></i>` : '<i class="kmapv-icon kmapv-icon-layers"></i>'),
title: options.title,
})
this.toggle.set('modal', true)
// si on ajoute ou supprimer des calques on rebuild la liste des calques
this.viewer.Map.getLayers().on('change:length', this.setLayerList.bind(this))
this.setLayerList()
return this.toggle
}
ControlBarLayerVisibility.prototype.setLayerList = function () {
// retire les event qu'on a posé sur core liés aux calques
coreLayerEvents.forEach(unByKey)
coreLayerEvents.splice(0, coreLayerEvents.length)
// retire la liste des calques actuels
this.toggle.setSubBar(null)
const layerIdProperty = this.viewer.commonLayer.propertiesName.ID_LAYER
const uiProperty = this.viewer.commonLayer.propertiesName.UI_LAYER
let controls = []
const backgroundLayers = this.viewer.commonLayer.getLayers('background')
// Il y a un background, on le mets dans la liste des boutons, il agira sur tous les backgrounds
if (backgroundLayers.length > 0) {
const ctrl = new Toggle({
html: '<i class="kmapv-icon kmapv-icon-map"></i>',
name: 'kmapv-layer-allbackground',
title: 'Fond de plan',
onToggle: onToggle.bind(this),
})
ctrl.set('layerid', '__allbackground')
ctrl.set('type', 'background')
// avant l'event change:active car celui-ci est appelé au chargement
setBackGroundActiveState.call(this, ctrl)
ctrl.on('change:active', toggleLayerVisibility.bind(this))
backgroundLayers.forEach(layer => {
const layerId = layer.get(layerIdProperty)
// abonnement a la visibilité d'un calque pour refleter le toggle si un evenement exterieur modifi l'état du groupe "background"
const listenerId = layer.on('change:visible', () => setBackGroundActiveState.call(this, ctrl))
coreLayerEvents.push(this.viewer.once(`removedLayer:${layerId}`, () => {
// Retire les events de la Map et la View liés au layer
unByKey(listenerId)
}))
})
controls.push(ctrl)
}
const datalayers = this.viewer.commonLayer.getLayers('data')
if (controls.length > 0 && datalayers.length > 0) {
const separator = new TextButton({
name: 'kmapv-separator',
className: 'separator',
text: '',
})
separator.set('type', 'separator')
controls.push(separator)
}
const layerCtrls = this.viewer.commonLayer.getLayers('data').filter(layer => layer.displayInLayerSwitcher !== false).map(layer => {
const layerId = layer.get(layerIdProperty)
const ui = layer.get(uiProperty)
const layerVisible = layer.getVisible()
const ctrl = new Toggle({
// html: ,
name: `kmapv-layer-${layerId}`,
onToggle: onToggle.bind(this),
className: layerVisible ? '' : 'faded',
active: layer.getVisible(),
title: ui?.title,
html: getButtonHtml(ui.html, ui.iconId, ui.icon, '<i class="kmapv-icon kmapv-icon-eye"></i>'),
})
ctrl.set('layerid', layerId)
ctrl.set('order', layer.getZIndex())
ctrl.set('type', 'data')
ctrl.on('change:active', toggleLayerVisibility.bind(this))
// abonnement a la visibilité d'un calque pour refleter le toggle si un evenement exterieur modifi l'état du calque
const listenerId = layer.on('change:visible', (e) => {
ctrl.setActive(e.target.get(e.key))
})
coreLayerEvents.push(this.viewer.once(`removedLayer:${layerId}`, () => {
// Retire les events de la Map et la View liés au layer
unByKey(listenerId)
}))
return ctrl
// controls.push(ctrl)
}).sort((a, b) => a.get('order') - b.get('order'))
controls = controls.concat(layerCtrls)
const bar = new Bar({
className: this.className,
group: true,
toggleOne: false,
controls,
})
this.toggle.setSubBar(bar)
}
export default ControlBarLayerVisibility