UNPKG

react-floorplanner

Version:

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

176 lines (154 loc) 6.41 kB
import React, {Component} from 'react'; import PropTypes from 'prop-types'; import If from '../../utils/react-if'; import FooterToggleButton from './footer-toggle-button'; import FooterContentButton from './footer-content-button'; import {SNAP_POINT, SNAP_LINE, SNAP_SEGMENT, SNAP_GRID, SNAP_MASK} from '../../utils/snap'; import {MODE_SNAPPING} from '../../constants'; import * as SharedStyle from '../../shared-style'; import IconClose from 'react-icons/lib/fa/close'; import MdAddCircle from 'react-icons/lib/md/add-circle'; import MdWarning from 'react-icons/lib/md/warning'; const footerBarStyle = { position: 'absolute', bottom: 0, lineHeight: '14px', fontSize: '12px', color: SharedStyle.COLORS.white, backgroundColor: SharedStyle.SECONDARY_COLOR.alt, padding: '3px 1em', margin: 0, boxSizing: 'border-box', cursor: 'default', userSelect: 'none', zIndex: '9001' }; export const leftTextStyle = { position: 'relative', borderRight: '1px solid #FFF', float: 'left', padding: '0 1em', display: 'inline-block' }; export const rightTextStyle = { position: 'relative', borderLeft: '1px solid #FFF', float: 'right', padding: '0 1em', display: 'inline-block' }; const coordStyle = { display: 'inline-block', width: '6em', margin: 0, padding: 0 }; export default class FooterBar extends Component { constructor(props) { super(props); this.state = {}; } render() { let {x, y} = this.props.state.get('mouse').toJS(); let zoom = this.props.state.get('zoom'); let mode = this.props.state.get('mode'); let errors = this.props.state.get('errors').toArray(); let errorsJsx = errors.map((err,ind) => <div key={ind} style={{borderBottom:'1px solid #555', lineHeight:'1.5em'}}>[ { (new Date(err.date)).toLocaleString() } ] {err.error}</div> ); let errorLableStyle = errors.length ? {color:SharedStyle.MATERIAL_COLORS[500].red} : {}; let errorIconStyle = errors.length ? {transform:'rotate(45deg)',color:SharedStyle.MATERIAL_COLORS[500].red} : {transform:'rotate(45deg)'}; let warnings = this.props.state.get('warnings').toArray(); let warningsJsx = warnings.map((warn,ind) => <div key={ind} style={{borderBottom:'1px solid #555', lineHeight:'1.5em'}}>[ { (new Date(warn.date)).toLocaleString() } ] {warn.warning}</div> ); let warningLableStyle = warnings.length ? {color:SharedStyle.MATERIAL_COLORS[500].yellow} : {}; let warningIconStyle = warningLableStyle; let updateSnapMask = (val) => this.context.projectActions.toggleSnap(this.props.state.snapMask.merge(val)); return ( <div style={{...footerBarStyle, width: this.props.width, height: this.props.height}}> <If condition={MODE_SNAPPING.includes(mode)}> <div style={leftTextStyle}> <div title={this.context.translator.t('Mouse X Coordinate')} style={coordStyle}>X : {x.toFixed(3)}</div> <div title={this.context.translator.t('Mouse Y Coordinate')} style={coordStyle}>Y : {y.toFixed(3)}</div> </div> <div style={leftTextStyle} title={this.context.translator.t('Scene Zoom Level')}>Zoom: {zoom.toFixed(3)}X</div> <div style={leftTextStyle}> <FooterToggleButton state={this.state} toggleOn={() => { updateSnapMask({SNAP_POINT: true}); }} toggleOff={() => { updateSnapMask({SNAP_POINT: false}); }} text="Snap PT" toggleState={this.props.state.snapMask.get(SNAP_POINT)} title={this.context.translator.t('Snap to Point')} /> <FooterToggleButton state={this.state} toggleOn={() => { updateSnapMask({SNAP_LINE: true}); }} toggleOff={() => { updateSnapMask({SNAP_LINE: false}); }} text="Snap LN" toggleState={this.props.state.snapMask.get(SNAP_LINE)} title={this.context.translator.t('Snap to Line')} /> <FooterToggleButton state={this.state} toggleOn={() => { updateSnapMask({SNAP_SEGMENT: true}); }} toggleOff={() => { updateSnapMask({SNAP_SEGMENT: false}); }} text="Snap SEG" toggleState={this.props.state.snapMask.get(SNAP_SEGMENT)} title={this.context.translator.t('Snap to Segment')} /> <FooterToggleButton state={this.state} toggleOn={() => { updateSnapMask({SNAP_GRID: true}); }} toggleOff={() => { updateSnapMask({SNAP_GRID: false}); }} text="Snap GRD" toggleState={this.props.state.snapMask.get(SNAP_GRID)} title={this.context.translator.t('Snap to Grid')} /> </div> </If> {this.props.footerbarComponents.map((Component, index) => <Component state={state} key={index}/>)} {this.props.softwareSignature ? <div style={rightTextStyle}>{this.props.softwareSignature}</div> : null} <div style={rightTextStyle}> <FooterContentButton state={this.state} icon={MdAddCircle} iconStyle={errorIconStyle} text={errors.length.toString()} textStyle={errorLableStyle} title={'Errors [ ' + errors.length + ' ]'} titleStyle={errorLableStyle} content={[errorsJsx]} /> <FooterContentButton state={this.state} icon={MdWarning} iconStyle={warningIconStyle} text={warnings.length.toString()} textStyle={warningLableStyle} title={'Warnings [ ' + warnings.length + ' ]'} titleStyle={warningLableStyle} content={[warningsJsx]} /> </div> </div> ); } } FooterBar.propTypes = { state: PropTypes.object.isRequired, footerbarComponents: PropTypes.array.isRequired, width: PropTypes.number.isRequired, height: PropTypes.number.isRequired, softwareSignature: PropTypes.string }; FooterBar.contextTypes = { projectActions: PropTypes.object.isRequired, viewer2DActions: PropTypes.object.isRequired, viewer3DActions: PropTypes.object.isRequired, linesActions: PropTypes.object.isRequired, holesActions: PropTypes.object.isRequired, itemsActions: PropTypes.object.isRequired, translator: PropTypes.object.isRequired, };