diff --git a/src/fields/propertygroup.jsx b/src/fields/propertygroup.jsx new file mode 100644 index 00000000..0cca9914 --- /dev/null +++ b/src/fields/propertygroup.jsx @@ -0,0 +1,50 @@ +import React from 'react' +import { ZoomSpecField } from './spec.jsx' +import Immutable from 'immutable' +import GlSpec from 'mapbox-gl-style-spec/reference/latest.min.js' +import theme from '../theme.js' + +console.log(ZoomSpecField) + +function getFieldSpec(layerType, fieldName) { + const paint = GlSpec['paint_' + layerType] || {} + const layout = GlSpec['layout_' + layerType] || {} + if (fieldName in paint) { + return paint[fieldName] + } else { + return layout[fieldName] + } +} + +export default class PropertyGroup extends React.Component { + static propTypes = { + layer: React.PropTypes.instanceOf(Immutable.Map).isRequired, + groupFields: React.PropTypes.instanceOf(Immutable.OrderedSet).isRequired, + onChange: React.PropTypes.func.isRequired, + } + + render() { + const fields = this.props.groupFields.map(fieldName => { + console.log(fieldName) + const fieldSpec = getFieldSpec(this.props.layer.get('type'), fieldName) + const fieldValue = this.props.layer.getIn(['paint', fieldName], this.props.layer.getIn(['layout', fieldName])) + + return + }).toIndexedSeq() + + return
+ {fields} +
+ } +} diff --git a/src/fields/spec.jsx b/src/fields/spec.jsx index ec792d31..d41c8d9e 100644 --- a/src/fields/spec.jsx +++ b/src/fields/spec.jsx @@ -24,7 +24,7 @@ const specFieldProps = { /** Supports displaying spec field for zoom function objects * https://www.mapbox.com/mapbox-gl-style-spec/#types-function-zoom-property */ -class ZoomSpecField extends React.Component { +export class ZoomSpecField extends React.Component { static propTypes = { ...specFieldProps, value: React.PropTypes.oneOfType([ @@ -167,30 +167,3 @@ class SpecField extends React.Component { } } } - -export class PropertyGroup extends React.Component { - static propTypes = { - onChange: React.PropTypes.func.isRequired, - properties: React.PropTypes.instanceOf(Immutable.Map).isRequired, - layerType: React.PropTypes.oneOf(['fill', 'background', 'line', 'symbol']).isRequired, - groupType: React.PropTypes.oneOf(['paint', 'layout']).isRequired, - } - - render() { - const layerTypeSpec = GlSpec[this.props.groupType + "_" + this.props.layerType] - const specFields = Object.keys(layerTypeSpec).filter(propName => propName !== 'visibility').map(propName => { - const fieldSpec = layerTypeSpec[propName] - const propValue = this.props.properties.get(propName) - return - }) - return
- {specFields} -
- } -} diff --git a/src/layers/editor.jsx b/src/layers/editor.jsx index d0e317ca..e89e2947 100644 --- a/src/layers/editor.jsx +++ b/src/layers/editor.jsx @@ -9,7 +9,7 @@ import Tabs from 'react-simpletabs' import theme from '../theme.js' import SourceEditor from './source.jsx' import FilterEditor from '../filter/editor.jsx' -import { PropertyGroup } from '../fields/spec.jsx' +import PropertyGroup from '../fields/propertygroup.jsx' import MdVisibility from 'react-icons/lib/md/visibility' import MdVisibilityOff from 'react-icons/lib/md/visibility-off' @@ -17,6 +17,7 @@ import MdDelete from 'react-icons/lib/md/delete' import PureRenderMixin from 'react-addons-pure-render-mixin'; import ScrollContainer from '../scrollcontainer.jsx' +import layout from '../layout.json' class UnsupportedLayer extends React.Component { render() { @@ -56,30 +57,13 @@ export class LayerEditor extends React.Component { } } - onPaintChanged(property, newValue) { - let layer = this.props.layer - //TODO: by using immutable records we can avoid this checking if object exists - // - if(!layer.has('paint')) { - layer = layer.set('paint', Immutable.Map()) - } - - const changedLayer = layer.setIn(['paint', property], newValue) + onPropertyChange(group, property, newValue) { + const layer = this.props.layer + const changedLayer = layer.setIn([group, property], newValue) this.props.onLayerChanged(changedLayer) } - onLayoutChanged(property, newValue) { - let layer = this.props.layer - //TODO: by using immutable records we can avoid this checking if object exists - if(!layer.has('layout')) { - layer = layer.set('layout', Immutable.Map()) - } - - const changedLayer = layer.setIn(['layout', property], newValue) - this.props.onLayerChanged(changedLayer) - } - - onFilterChanged(newValue) { + onFilterChange(newValue) { let layer = this.props.layer const changedLayer = layer.set('filter', newValue) this.props.onLayerChanged(changedLayer) @@ -94,17 +78,26 @@ export class LayerEditor extends React.Component { } render() { + const layerType = this.props.layer.get('type') + const groups = layout[layerType].groups + const propertyGroups = groups.map(group => { + return + }) + let visibleIcon = if(this.props.layer.has('layout') && this.props.layer.getIn(['layout', 'visibility']) === 'none') { visibleIcon = } - return
+ }}> - #{this.props.layer.get('id')} + {this.props.layer.get('id')} @@ -114,42 +107,19 @@ export class LayerEditor extends React.Component { - - -
- -
-
- -
- -
-
- + {propertyGroups} this.onFilterChanged(Immutable.fromJS(f))} + onChange={f => this.onFilterChange(Immutable.fromJS(f))} /> - {this.props.layer.get('type') !== 'background' && } - -
} } - diff --git a/src/layout.json b/src/layout.json new file mode 100644 index 00000000..c2e67c23 --- /dev/null +++ b/src/layout.json @@ -0,0 +1,116 @@ +{ + "line": { + "groups": [ + { + "title": "Paint", + "fields": [ + "line-opacity", + "line-color", + "line-width", + "line-offset", + "line-blur", + "line-pattern" + ] + }, + { + "title": "Secondary", + "fields": [ + "line-translate", + "line-translate-anchor", + "line-cap", + "line-join", + "line-miter-limit", + "line-round-limit", + "line-dasharray", + "line-gap-width" + ] + } + ] + }, + "background": { + "groups": [ + { + "title": "primary", + "fields": [ + "background-color", + "background-pattern", + "background-opacity" + ] + } + ] + }, + "fill": { + "groups": [ + { + "title": "primary", + "fields": [ + "fill-opacity", + "fill-color", + "fill-antialias", + "fill-outline-color", + "fill-pattern", + "fill-translate", + "fill-translate-anchor" + ] + } + ] + }, + "symbol": { + "groups": [ + { + "title": "primary", + "fields": [ + "text-field", + "text-font", + "text-size", + "text-line-height" + ] + }, + { + "title": "placement", + "fields": [ + "symbol-placement", + "symbol-spacing", + "symbol-avoid-edges", + "text-padding", + "text-allow-overlap", + "text-ignore-placement" + ] + }, + { + "title": "layout", + "fields": [ + "text-pitch-alignment", + "text-rotation-alignment", + "text-max-width", + "text-letter-spacing", + "text-justify", + "text-anchor", + "text-max-angle", + "text-rotate", + "text-keep-upright", + "text-transform", + "text-offset", + "text-optional" + ] + }, + { + "title": "icon", + "fields": [ + "icon-allow-overlap", + "icon-ignore-placement", + "icon-optional", + "icon-rotation-alignment", + "icon-size", + "icon-text-fit", + "icon-text-fit-padding", + "icon-image", + "icon-rotate", + "icon-padding", + "icon-keep-upright", + "icon-offset" + ] + } + ] + } +}