maputnik/src/components/layers/LayerEditor.jsx

162 lines
4.7 KiB
React
Raw Normal View History

2016-09-10 14:10:25 +02:00
import React from 'react'
2016-09-10 16:53:58 +02:00
import GlSpec from 'mapbox-gl-style-spec/reference/latest.min.js'
2016-12-22 15:27:58 +01:00
import JSONEditor from './JSONEditor'
2016-12-20 11:44:22 +01:00
import FilterEditor from '../filter/FilterEditor'
import PropertyGroup from '../fields/PropertyGroup'
2016-12-21 11:24:32 +01:00
import LayerEditorGroup from './LayerEditorGroup'
import LayerTypeBlock from './LayerTypeBlock'
import LayerIdBlock from './LayerIdBlock'
import LayerSourceBlock from './LayerSourceBlock'
import LayerSourceLayerBlock from './LayerSourceLayerBlock'
2016-12-19 15:40:11 +01:00
2016-12-28 16:48:49 +01:00
import InputBlock from '../inputs/InputBlock'
import MultiButtonInput from '../inputs/MultiButtonInput'
2016-12-31 14:02:14 +01:00
import input from '../../config/input.js'
2016-12-30 16:56:20 +01:00
import { changeType, changeProperty } from '../../libs/layer'
2016-12-20 11:44:22 +01:00
import layout from '../../config/layout.json'
2016-12-21 14:46:51 +01:00
import { margins, fontSizes } from '../../config/scales'
import colors from '../../config/colors'
2016-12-17 20:19:01 +01:00
2016-09-10 14:10:25 +02:00
class UnsupportedLayer extends React.Component {
2016-12-17 15:44:42 +01:00
render() {
return <div></div>
}
2016-09-10 14:10:25 +02:00
}
/** Layer editor supporting multiple types of layers. */
2016-12-20 11:44:22 +01:00
export default class LayerEditor extends React.Component {
2016-12-17 15:44:42 +01:00
static propTypes = {
layer: React.PropTypes.object.isRequired,
2016-12-20 16:08:49 +01:00
sources: React.PropTypes.object,
vectorLayers: React.PropTypes.object,
2016-12-17 15:44:42 +01:00
onLayerChanged: React.PropTypes.func,
2016-12-22 15:49:36 +01:00
onLayerIdChange: React.PropTypes.func,
2016-12-17 15:44:42 +01:00
}
static defaultProps = {
onLayerChanged: () => {},
2016-12-22 15:49:36 +01:00
onLayerIdChange: () => {},
2016-12-17 15:44:42 +01:00
onLayerDestroyed: () => {},
}
static childContextTypes = {
reactIconBase: React.PropTypes.object
}
constructor(props) {
2016-12-21 11:24:32 +01:00
super(props)
//TODO: Clean this up and refactor into function
const editorGroups = {}
layout[this.props.layer.type].groups.forEach(group => {
editorGroups[group.title] = true
})
this.state = { editorGroups }
}
componentWillReceiveProps(nextProps) {
const additionalGroups = { ...this.state.editorGroups }
layout[nextProps.layer.type].groups.forEach(group => {
if(!(group.title in additionalGroups)) {
additionalGroups[group.title] = true
}
})
this.setState({
editorGroups: additionalGroups
})
2016-12-17 15:44:42 +01:00
}
getChildContext () {
return {
reactIconBase: {
2016-12-21 14:46:51 +01:00
size: fontSizes[4],
color: colors.lowgray,
2016-12-17 15:44:42 +01:00
}
}
}
changeProperty(group, property, newValue) {
2016-12-30 16:56:20 +01:00
this.props.onLayerChanged(changeProperty(this.props.layer, group, property, newValue))
2016-12-19 14:56:10 +01:00
}
2016-12-21 11:24:32 +01:00
onGroupToggle(groupTitle, active) {
const changedActiveGroups = {
...this.state.editorGroups,
[groupTitle]: active,
}
this.setState({
editorGroups: changedActiveGroups
})
}
renderGroupType(type, fields) {
switch(type) {
case 'settings': return <div>
<LayerIdBlock
value={this.props.layer.id}
onChange={newId => this.props.onLayerIdChange(this.props.layer.id, newId)}
/>
<LayerTypeBlock
value={this.props.layer.type}
onChange={newType => this.props.onLayerChanged(changeType(this.props.layer, newType))}
/>
</div>
case 'source': return <div>
<LayerSourceBlock
sourceIds={Object.keys(this.props.sources)}
value={this.props.layer.source}
onChange={v => this.changeProperty(null, 'source', v)}
/>
2017-01-08 19:58:19 +01:00
{this.props.layer.type !== 'raster' && <LayerSourceLayerBlock
sourceLayerIds={this.props.sources[this.props.layer.source]}
value={this.props.layer['source-layer']}
onChange={v => this.changeProperty(null, 'source-layer', v)}
2016-12-21 11:24:32 +01:00
/>
2017-01-08 19:58:19 +01:00
}
2016-12-31 14:02:14 +01:00
<div style={input.property}>
<FilterEditor
filter={this.props.layer.filter}
properties={this.props.vectorLayers[this.props.layer['source-layer']]}
onChange={f => this.changeProperty(null, 'filter', f)}
/>
</div>
</div>
case 'properties': return <PropertyGroup
layer={this.props.layer}
groupFields={fields}
onChange={this.changeProperty.bind(this)}
/>
2016-12-22 15:27:58 +01:00
case 'jsoneditor': return <JSONEditor
layer={this.props.layer}
onChange={this.props.onLayerChanged}
/>
default: return null
2016-12-21 11:24:32 +01:00
}
}
2016-12-21 11:24:32 +01:00
render() {
const layerType = this.props.layer.type
const layoutGroups = layout[layerType].groups.filter(group => {
return !(this.props.layer.type === 'background' && group.type === 'source')
}).map(group => {
return <LayerEditorGroup
key={group.title}
title={group.title}
isActive={this.state.editorGroups[group.title]}
onActiveToggle={this.onGroupToggle.bind(this, group.title)}
>
{this.renderGroupType(group.type, group.fields)}
</LayerEditorGroup>
})
2016-12-22 13:40:23 +01:00
2016-12-22 12:06:04 +01:00
return <div>
{layoutGroups}
2016-12-17 15:44:42 +01:00
</div>
}
2016-09-10 14:10:25 +02:00
}