2016-12-17 16:43:25 +01:00
|
|
|
import React from 'react'
|
2016-12-19 11:46:48 +01:00
|
|
|
import Color from 'color'
|
2016-12-17 16:43:25 +01:00
|
|
|
|
2016-12-20 19:20:56 +01:00
|
|
|
import CopyIcon from 'react-icons/lib/md/content-copy'
|
|
|
|
import VisibilityIcon from 'react-icons/lib/md/visibility'
|
|
|
|
import VisibilityOffIcon from 'react-icons/lib/md/visibility-off'
|
|
|
|
import DeleteIcon from 'react-icons/lib/md/delete'
|
|
|
|
|
2016-12-20 11:44:22 +01:00
|
|
|
import LayerIcon from '../icons/LayerIcon'
|
|
|
|
import LayerEditor from './LayerEditor'
|
|
|
|
import {SortableElement, SortableHandle} from 'react-sortable-hoc'
|
|
|
|
|
|
|
|
import colors from '../../config/colors.js'
|
|
|
|
import { fontSizes, margins } from '../../config/scales.js'
|
2016-12-17 16:43:25 +01:00
|
|
|
|
2016-12-18 17:28:59 +01:00
|
|
|
|
|
|
|
@SortableHandle
|
|
|
|
class LayerTypeDragHandle extends React.Component {
|
|
|
|
static propTypes = LayerIcon.propTypes
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return <LayerIcon
|
|
|
|
{...this.props}
|
2016-12-22 13:40:23 +01:00
|
|
|
style={{
|
|
|
|
cursor: 'move',
|
2016-12-25 17:46:18 +01:00
|
|
|
width: fontSizes[4],
|
|
|
|
height: fontSizes[4],
|
2016-12-22 13:40:23 +01:00
|
|
|
paddingRight: margins[0],
|
|
|
|
}}
|
2016-12-18 17:28:59 +01:00
|
|
|
/>
|
|
|
|
}
|
|
|
|
}
|
2016-12-17 19:58:30 +01:00
|
|
|
|
2016-12-20 19:20:56 +01:00
|
|
|
class IconAction extends React.Component {
|
|
|
|
static propTypes = {
|
|
|
|
action: React.PropTypes.string.isRequired,
|
|
|
|
active: React.PropTypes.bool,
|
2016-12-20 20:21:35 +01:00
|
|
|
onClick: React.PropTypes.func.isRequired,
|
2016-12-20 19:20:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props)
|
|
|
|
this.state = { hover: false }
|
|
|
|
}
|
|
|
|
|
|
|
|
renderIcon() {
|
|
|
|
const iconStyle = {
|
2016-12-20 20:36:02 +01:00
|
|
|
fill: colors.black
|
2016-12-20 20:21:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if(this.props.active) {
|
|
|
|
iconStyle.fill = colors.midgray
|
|
|
|
}
|
|
|
|
if(this.state.hover) {
|
|
|
|
iconStyle.fill = colors.lowgray
|
2016-12-20 19:20:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
switch(this.props.action) {
|
|
|
|
case 'copy': return <CopyIcon style={iconStyle} />
|
2016-12-20 20:21:35 +01:00
|
|
|
case 'show': return <VisibilityIcon style={iconStyle} />
|
2016-12-20 19:20:56 +01:00
|
|
|
case 'hide': return <VisibilityOffIcon style={iconStyle} />
|
|
|
|
case 'delete': return <DeleteIcon style={iconStyle} />
|
|
|
|
default: return null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2016-12-20 20:21:35 +01:00
|
|
|
return <a
|
2016-12-20 19:20:56 +01:00
|
|
|
style={{
|
|
|
|
display: "inline",
|
|
|
|
marginLeft: margins[0],
|
|
|
|
...this.props.style
|
|
|
|
}}
|
2016-12-20 20:21:35 +01:00
|
|
|
onClick={this.props.onClick}
|
2016-12-20 19:20:56 +01:00
|
|
|
onMouseOver={e => this.setState({hover: true})}
|
|
|
|
onMouseOut={e => this.setState({hover: false})}
|
|
|
|
>
|
|
|
|
{this.renderIcon()}
|
2016-12-20 20:21:35 +01:00
|
|
|
</a>
|
2016-12-20 19:20:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-17 19:58:30 +01:00
|
|
|
@SortableElement
|
2016-12-17 16:43:25 +01:00
|
|
|
class LayerListItem extends React.Component {
|
|
|
|
static propTypes = {
|
2016-12-17 19:58:30 +01:00
|
|
|
layerId: React.PropTypes.string.isRequired,
|
2016-12-18 17:28:59 +01:00
|
|
|
layerType: React.PropTypes.string.isRequired,
|
2016-12-20 19:20:56 +01:00
|
|
|
isSelected: React.PropTypes.bool,
|
2016-12-20 20:21:35 +01:00
|
|
|
visibility: React.PropTypes.string,
|
2016-12-20 19:20:56 +01:00
|
|
|
|
2016-12-20 20:21:35 +01:00
|
|
|
onLayerSelect: React.PropTypes.func.isRequired,
|
|
|
|
onLayerCopy: React.PropTypes.func,
|
|
|
|
onLayerDestroy: React.PropTypes.func,
|
|
|
|
onLayerVisibilityToggle: React.PropTypes.func,
|
2016-12-20 19:20:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static defaultProps = {
|
|
|
|
isSelected: false,
|
2016-12-20 20:21:35 +01:00
|
|
|
visibility: 'visible',
|
|
|
|
onLayerCopy: () => {},
|
|
|
|
onLayerDestroy: () => {},
|
|
|
|
onLayerVisibilityToggle: () => {},
|
2016-12-20 19:20:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static childContextTypes = {
|
|
|
|
reactIconBase: React.PropTypes.object
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props)
|
|
|
|
this.state = {
|
|
|
|
hover: false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getChildContext() {
|
|
|
|
return {
|
2016-12-25 17:46:18 +01:00
|
|
|
reactIconBase: { size: fontSizes[4] }
|
2016-12-20 19:20:56 +01:00
|
|
|
}
|
2016-12-17 16:43:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2016-12-20 19:20:56 +01:00
|
|
|
const itemStyle = {
|
|
|
|
fontWeight: 400,
|
2017-01-10 19:41:39 +01:00
|
|
|
color: this.props.isSelected ? colors.white : colors.lowgray,
|
2016-12-20 19:20:56 +01:00
|
|
|
fontSize: fontSizes[5],
|
|
|
|
borderLeft: 0,
|
|
|
|
borderTop: 0,
|
|
|
|
borderBottom: 1,
|
|
|
|
borderRight: 0,
|
|
|
|
borderStyle: "solid",
|
|
|
|
userSelect: 'none',
|
|
|
|
listStyle: 'none',
|
|
|
|
zIndex: 2000,
|
|
|
|
cursor: 'pointer',
|
|
|
|
position: 'relative',
|
|
|
|
padding: margins[1],
|
2017-01-10 19:41:39 +01:00
|
|
|
paddingLeft: margins[2],
|
|
|
|
paddingRight: margins[2],
|
2016-12-20 20:36:02 +01:00
|
|
|
borderColor: Color(colors.black).lighten(0.10).string(),
|
|
|
|
backgroundColor: colors.black,
|
2016-12-26 11:22:41 +01:00
|
|
|
lineHeight: 1.3,
|
2016-12-20 19:20:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if(this.state.hover) {
|
2016-12-20 20:36:02 +01:00
|
|
|
itemStyle.backgroundColor = Color(colors.black).lighten(0.10).string()
|
2016-12-20 19:20:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if(this.props.isSelected) {
|
2016-12-20 20:36:02 +01:00
|
|
|
itemStyle.backgroundColor = Color(colors.black).lighten(0.15).string()
|
2016-12-20 19:20:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const iconProps = {
|
|
|
|
active: this.state.hover || this.props.isSelected
|
|
|
|
}
|
|
|
|
|
2016-12-17 19:58:30 +01:00
|
|
|
return <li
|
|
|
|
key={this.props.layerId}
|
2016-12-20 20:21:35 +01:00
|
|
|
onClick={e => this.props.onLayerSelect(this.props.layerId)}
|
2016-12-20 19:20:56 +01:00
|
|
|
onMouseOver={e => this.setState({hover: true})}
|
|
|
|
onMouseOut={e => this.setState({hover: false})}
|
|
|
|
style={itemStyle}>
|
|
|
|
<div style={{
|
|
|
|
display: 'flex',
|
|
|
|
flexDirection: 'row'
|
|
|
|
}}>
|
|
|
|
<LayerTypeDragHandle type={this.props.layerType} />
|
|
|
|
<span style={{
|
|
|
|
width: 115,
|
|
|
|
whiteSpace: 'nowrap',
|
|
|
|
overflow: 'hidden',
|
|
|
|
textOverflow: 'ellipsis'
|
|
|
|
}}>{this.props.layerId}</span>
|
|
|
|
<span style={{flexGrow: 1}} />
|
|
|
|
<IconAction {...iconProps}
|
|
|
|
action={'delete'}
|
2016-12-20 20:21:35 +01:00
|
|
|
onClick={e => this.props.onLayerDestroy(this.props.layerId)}
|
2016-12-20 19:20:56 +01:00
|
|
|
/>
|
|
|
|
<IconAction {...iconProps}
|
|
|
|
action={'copy'}
|
2016-12-20 20:21:35 +01:00
|
|
|
onClick={e => this.props.onLayerCopy(this.props.layerId)}
|
2016-12-20 19:20:56 +01:00
|
|
|
/>
|
|
|
|
<IconAction {...iconProps}
|
2016-12-20 20:21:35 +01:00
|
|
|
active={this.state.hover || this.props.isSelected || this.props.visibility === 'none'}
|
|
|
|
action={this.props.visibility === 'visible' ? 'hide' : 'show'}
|
|
|
|
onClick={e => this.props.onLayerVisibilityToggle(this.props.layerId)}
|
2016-12-20 19:20:56 +01:00
|
|
|
/>
|
|
|
|
</div>
|
2016-12-17 19:58:30 +01:00
|
|
|
</li>
|
2016-12-17 16:43:25 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-20 19:20:56 +01:00
|
|
|
export default LayerListItem;
|