UNPKG

react-floorplanner

Version:

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

193 lines (174 loc) 5.71 kB
import React, {Component} from 'react'; import PropTypes from 'prop-types'; import IconNewFile from 'react-icons/lib/fa/file-o'; import IconPointer from 'react-icons/lib/fa/mouse-pointer'; import Icon3DFirstPerson from 'react-icons/lib/md/directions-run'; import IconCatalog from 'react-icons/lib/fa/plus'; import IconUndo from 'react-icons/lib/md/undo'; import IconConfigure from 'react-icons/lib/md/settings'; import ToolbarButton from './toolbar-button'; import ToolbarSaveButton from './toolbar-save-button'; import ToolbarLoadButton from './toolbar-load-button'; import If from '../../utils/react-if'; import { MODE_IDLE, MODE_3D_VIEW, MODE_3D_FIRST_PERSON, MODE_VIEWING_CATALOG, MODE_CONFIGURING_PROJECT } from '../../constants'; import * as SharedStyle from '../../shared-style'; const Icon2D = () => <p style={{ fontSize: '19px', textDecoration: 'none', fontWeight: 'bold', margin: '0px' }}>2D</p>; const Icon3D = () => <p style={{ fontSize: '19px', textDecoration: 'none', fontWeight: 'bold', margin: '0px' }}>3D</p>; const ASIDE_STYLE = { backgroundColor: SharedStyle.PRIMARY_COLOR.main, padding: '10px' }; const sortButtonsCb = (a, b) => { if (a.index === undefined || a.index === null) { a.index = Number.MAX_SAFE_INTEGER; } if (b.index === undefined || b.index === null) { b.index = Number.MAX_SAFE_INTEGER; } return a.index - b.index; }; const mapButtonsCb = (el, ind) => { return ( <If key={ind} condition={el.condition} style={{position: 'relative'}} > {el.dom} </If> ); }; export default class Toolbar extends Component { constructor(props, context) { super(props, context); this.state = {}; } shouldComponentUpdate(nextProps, nextState) { return this.props.state.mode !== nextProps.state.mode || this.props.height !== nextProps.height || this.props.width !== nextProps.width; } render() { let { props: {state, width, height, toolbarButtons, allowProjectFileSupport}, context: {projectActions, viewer3DActions, translator} } = this; let mode = state.get('mode'); let sorter = [ { index: 0, condition: allowProjectFileSupport, dom: <ToolbarButton active={false} tooltip={translator.t('New project')} onClick={event => confirm(translator.t('Would you want to start a new Project?')) ? projectActions.newProject() : null}> <IconNewFile/> </ToolbarButton> }, { index: 1, condition: allowProjectFileSupport, dom: <ToolbarSaveButton state={state}/> }, { index: 2, condition: allowProjectFileSupport, dom: <ToolbarLoadButton state={state}/> }, { index: 3, condition: true, dom: <ToolbarButton active={[MODE_VIEWING_CATALOG].includes(mode)} tooltip={translator.t('Open catalog')} onClick={event => projectActions.openCatalog()}> <IconCatalog/> </ToolbarButton> }, { index: 4, condition: true, dom: <ToolbarButton active={[MODE_3D_VIEW].includes(mode)} tooltip={translator.t('3D View')} onClick={event => viewer3DActions.selectTool3DView()}> <Icon3D/> </ToolbarButton> }, { index: 5, condition: true, dom: <ToolbarButton active={[MODE_IDLE].includes(mode)} tooltip={translator.t('2D View')} onClick={event => projectActions.rollback()}> {[MODE_3D_FIRST_PERSON, MODE_3D_VIEW].includes(mode) ? <Icon2D/> : <IconPointer/>} </ToolbarButton> }, { index: 6, condition: true, dom: <ToolbarButton active={[MODE_3D_FIRST_PERSON].includes(mode)} tooltip={translator.t('3D First Person')} onClick={event => viewer3DActions.selectTool3DFirstPerson()}> <Icon3DFirstPerson/> </ToolbarButton> }, { index: 7, condition: true, dom: <ToolbarButton active={false} tooltip={translator.t('Undo (CTRL-Z)')} onClick={event => projectActions.undo()}> <IconUndo/> </ToolbarButton> }, { index: 8, condition: true, dom: <ToolbarButton active={[MODE_CONFIGURING_PROJECT].includes(mode)} tooltip={translator.t('Configure project')} onClick={event => projectActions.openProjectConfigurator()}> <IconConfigure/> </ToolbarButton> } ]; sorter = sorter.concat(toolbarButtons.map((Component, key) => { return Component.prototype ? //if is a react component { condition: true, dom: React.createElement(Component, {mode, state, key}) } : { //else is a sortable toolbar button index: Component.index, condition: Component.condition, dom: React.createElement(Component.dom, {mode, state, key}) }; })); return ( <aside style={{...ASIDE_STYLE, maxWidth: width, maxHeight: height}} className='toolbar'> {sorter.sort(sortButtonsCb).map(mapButtonsCb)} </aside> ) } } Toolbar.propTypes = { state: PropTypes.object.isRequired, width: PropTypes.number.isRequired, height: PropTypes.number.isRequired, allowProjectFileSupport: PropTypes.bool.isRequired, toolbarButtons: PropTypes.array }; Toolbar.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, };