UNPKG

react-planner

Version:

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

189 lines (170 loc) 5.87 kB
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { MdSettings, MdUndo, MdDirectionsRun } from 'react-icons/md'; import { FaFile, FaMousePointer, FaPlus } from 'react-icons/fa'; 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 iconTextStyle = { fontSize: '19px', textDecoration: 'none', fontWeight: 'bold', margin: '0px', userSelect: 'none' }; const Icon2D = ( {style} ) => <p style={{...iconTextStyle, ...style}}>2D</p>; const Icon3D = ( {style} ) => <p style={{...iconTextStyle, ...style}}>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 || this.props.state.alterate !== nextProps.state.alterate; } render() { let { props: { state, width, height, toolbarButtons, allowProjectFileSupport }, context: { projectActions, viewer3DActions, translator } } = this; let mode = state.get('mode'); let alterate = state.get('alterate'); let alterateColor = alterate ? SharedStyle.MATERIAL_COLORS[500].orange : ''; 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}> <FaFile /> </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()}> <FaPlus /> </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.setMode( MODE_IDLE )}> {[MODE_3D_FIRST_PERSON, MODE_3D_VIEW].includes(mode) ? <Icon2D style={{color: alterateColor}} /> : <FaMousePointer style={{color: alterateColor}} />} </ToolbarButton> }, { index: 6, condition: true, dom: <ToolbarButton active={[MODE_3D_FIRST_PERSON].includes(mode)} tooltip={translator.t('3D First Person')} onClick={event => viewer3DActions.selectTool3DFirstPerson()}> <MdDirectionsRun /> </ToolbarButton> }, { index: 7, condition: true, dom: <ToolbarButton active={false} tooltip={translator.t('Undo (CTRL-Z)')} onClick={event => projectActions.undo()}> <MdUndo /> </ToolbarButton> }, { index: 8, condition: true, dom: <ToolbarButton active={[MODE_CONFIGURING_PROJECT].includes(mode)} tooltip={translator.t('Configure project')} onClick={event => projectActions.openProjectConfigurator()}> <MdSettings /> </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, };