UNPKG

react-planner-electron

Version:

react-planner-electron is a React Component for plans design. Draw a 2D floorplan and navigate it in 3D mode.

213 lines (186 loc) 8.14 kB
import React, {Component} from 'react'; import PropTypes from 'prop-types'; import Panel from './panel'; import * as SharedStyle from '../../shared-style'; import {TiPlus, TiDelete} from 'react-icons/ti'; import {FaTrash, FaEye, FaLink, FaUnlink} from 'react-icons/fa'; import { Map } from 'immutable'; import { MODE_IDLE, MODE_2D_ZOOM_IN, MODE_2D_ZOOM_OUT, MODE_2D_PAN, MODE_3D_VIEW, MODE_3D_FIRST_PERSON, MODE_WAITING_DRAWING_LINE, MODE_DRAWING_LINE, MODE_DRAWING_HOLE, MODE_DRAWING_ITEM, MODE_DRAGGING_LINE, MODE_DRAGGING_VERTEX, MODE_DRAGGING_ITEM, MODE_DRAGGING_HOLE, MODE_FITTING_IMAGE, MODE_UPLOADING_IMAGE, MODE_ROTATING_ITEM } from '../../constants'; const VISIBILITY_MODE = { MODE_IDLE, MODE_2D_ZOOM_IN, MODE_2D_ZOOM_OUT, MODE_2D_PAN, MODE_3D_VIEW, MODE_3D_FIRST_PERSON, MODE_WAITING_DRAWING_LINE, MODE_DRAWING_LINE, MODE_DRAWING_HOLE, MODE_DRAWING_ITEM, MODE_DRAGGING_LINE, MODE_DRAGGING_VERTEX, MODE_DRAGGING_ITEM, MODE_DRAGGING_HOLE, MODE_FITTING_IMAGE, MODE_UPLOADING_IMAGE, MODE_ROTATING_ITEM }; const styleEditButton = { marginLeft: '5px', border: '0px', background: 'none', color: SharedStyle.COLORS.white, fontSize: '14px', outline: '0px' }; const tablegroupStyle = { width: '100%', cursor: 'pointer', maxHeight: '20em', padding: '0 1em', marginLeft: '1px' }; const iconColStyle = {width: '2em', textAlign: 'center'}; const styleHoverColor = {color: SharedStyle.SECONDARY_COLOR.main}; const styleEditButtonHover = {...styleEditButton, ...styleHoverColor}; const styleAddLabel = {fontSize: '10px', marginLeft: '5px'}; const styleEyeVisible = {fontSize: '1.25em'}; const styleEyeHidden = {...styleEyeVisible, color: '#a5a1a1'}; const newLayerLableStyle = {fontSize: '1.3em', cursor: 'pointer', textAlign: 'center'}; const newLayerLableHoverStyle = {...newLayerLableStyle, ...styleHoverColor}; export default class PanelGroups extends Component { constructor(props, context) { super(props, context); this.state = { newEmptyHover: false, newSelectedHover: false }; } shouldComponentUpdate(nextProps, nextState) { return ( this.props.groups.hashCode() !== nextProps.groups.hashCode() || this.props.layers.hashCode() !== nextProps.layers.hashCode() || this.props.mode !== nextProps.mode ); } render() { let { mode, groups, layers } = this.props; if (!VISIBILITY_MODE[ mode ]) return null; return ( <Panel name={this.context.translator.t('Groups')} opened={groups.size > 0}> { groups.size ? <table style={tablegroupStyle}> <thead> <tr> <th colSpan="4"></th> <th>{this.context.translator.t('Elements')}</th> <th>{this.context.translator.t('Name')}</th> </tr> </thead> <tbody> { groups.entrySeq().map(([ groupID, group ]) => { let selectClick = e => this.context.groupsActions.selectGroup(groupID); let swapVisibility = e => { e.stopPropagation(); this.context.groupsActions.setGroupProperties(groupID, new Map({visible: !group.get('visible')})); }; let chainToGroup = e => { layers.forEach((layer) => { let layerID = layer.get('id'); let layerElements = { 'lines': layer.get('lines'), 'items': layer.get('items'), 'holes': layer.get('holes'), 'areas': layer.get('areas') }; for( let elementPrototype in layerElements ) { let ElementList = layerElements[elementPrototype]; ElementList.filter( el => el.get('selected') ).forEach( element => { this.context.groupsActions.addToGroup( groupID, layerID, elementPrototype, element.get('id') ); }); } }); selectClick(e); }; let isCurrentgroup = group.get('selected'); let shouldHighlight = isCurrentgroup; let rowStyle = !shouldHighlight ? null : styleHoverColor; let dimension = group.get('elements').reduce( ( sum, layer ) => { return sum + layer.reduce( ( lSum, elProt ) => lSum + elProt.size, 0 ); }, 0); return ( <tr key={groupID} style={rowStyle} > <td style={iconColStyle} title={this.context.translator.t('Toggle Group Visibility')}> <FaEye onClick={swapVisibility} style={!group.get('visible') ? styleEyeHidden : styleEyeVisible} /> </td> <td style={iconColStyle} title={this.context.translator.t('Chain selected Elements to Group')}> <FaLink onClick={chainToGroup} style={!shouldHighlight ? styleEditButton : styleEditButtonHover} /> </td> <td style={iconColStyle} title={this.context.translator.t('Un-chain all Group\'s Elements and remove Group')}> <FaUnlink onClick={ e => this.context.groupsActions.removeGroup(groupID) } style={!shouldHighlight ? styleEditButton : styleEditButtonHover} /> </td> <td style={iconColStyle} title={this.context.translator.t('Delete group and all Elements')}> <FaTrash onClick={ e => this.context.groupsActions.removeGroupAndDeleteElements(groupID) } style={!shouldHighlight ? styleEditButton : styleEditButtonHover} /> </td> <td onClick={selectClick} style={{width:'0em', textAlign:'center'}}> { dimension } </td> <td onClick={selectClick}> {group.get('name')} </td> </tr> ); }) } </tbody> </table> : null } <table style={{width:'100%', marginTop: '0.1em'}}> <tbody> <tr> <td style={ !this.state.newEmptyHover ? newLayerLableStyle : newLayerLableHoverStyle } onMouseOver={ () => this.setState({newEmptyHover: true}) } onMouseOut={ () => this.setState({newEmptyHover: false}) } onClick={ e => this.context.groupsActions.addGroup() } > <TiPlus /> <b style={styleAddLabel}>{this.context.translator.t('New Empty Group')}</b> </td> <td style={ !this.state.newSelectedHover ? newLayerLableStyle : newLayerLableHoverStyle } onMouseOver={ () => this.setState({newSelectedHover: true}) } onMouseOut={ () => this.setState({newSelectedHover: false}) } onClick={ e => this.context.groupsActions.addGroupFromSelected() } > <TiPlus /> <b style={styleAddLabel}>{this.context.translator.t('New Group from selected')}</b> </td> </tr> </tbody> </table> </Panel> ) } } PanelGroups.propTypes = { mode: PropTypes.string.isRequired, groups: PropTypes.object.isRequired, layers: PropTypes.object.isRequired }; PanelGroups.contextTypes = { catalog: PropTypes.object.isRequired, translator: PropTypes.object.isRequired, itemsActions: PropTypes.object.isRequired, linesActions: PropTypes.object.isRequired, holesActions: PropTypes.object.isRequired, groupsActions: PropTypes.object.isRequired, projectActions: PropTypes.object.isRequired };