diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/map/MapConstants.js | 2 | ||||
| -rw-r--r-- | src/components/map/MapStage.js | 74 | ||||
| -rw-r--r-- | src/components/modals/Modal.js | 3 | ||||
| -rw-r--r-- | src/components/sidebars/topology/NameComponent.js | 13 | ||||
| -rw-r--r-- | src/components/sidebars/topology/room/RoomNameComponent.js | 9 | ||||
| -rw-r--r-- | src/components/sidebars/topology/room/RoomSidebarComponent.js | 14 | ||||
| -rw-r--r-- | src/components/sidebars/topology/room/RoomTypeComponent.js | 10 | ||||
| -rw-r--r-- | src/containers/sidebars/topology/room/RoomTypeContainer.js | 14 | ||||
| -rw-r--r-- | src/pages/App.js | 13 | ||||
| -rw-r--r-- | src/shortcuts/keymap.js | 10 | ||||
| -rw-r--r-- | src/util/room-types.js | 7 |
11 files changed, 137 insertions, 32 deletions
diff --git a/src/components/map/MapConstants.js b/src/components/map/MapConstants.js index eca8e516..69fdb419 100644 --- a/src/components/map/MapConstants.js +++ b/src/components/map/MapConstants.js @@ -8,3 +8,5 @@ export const OBJECT_SIZE_IN_PIXELS = TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXE export const GRID_LINE_WIDTH_IN_PIXELS = 2; export const WALL_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 8; export const OBJECT_BORDER_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 12; + +export const MAP_MOVE_PIXELS_PER_EVENT = 20; diff --git a/src/components/map/MapStage.js b/src/components/map/MapStage.js index 541df1d6..f3f38917 100644 --- a/src/components/map/MapStage.js +++ b/src/components/map/MapStage.js @@ -1,12 +1,13 @@ import React from "react"; import {Group, Layer, Stage} from "react-konva"; +import {Shortcuts} from "react-shortcuts"; import DatacenterContainer from "../../containers/map/DatacenterContainer"; import HoverTileLayer from "../../containers/map/layers/HoverTileLayer"; import jQuery from "../../util/jquery"; import {NAVBAR_HEIGHT} from "../navigation/Navbar"; import Backdrop from "./elements/Backdrop"; import GridGroup from "./groups/GridGroup"; -import {MAP_SIZE_IN_PIXELS} from "./MapConstants"; +import {MAP_MOVE_PIXELS_PER_EVENT, MAP_SIZE_IN_PIXELS} from "./MapConstants"; class MapStage extends React.Component { state = { @@ -39,12 +40,33 @@ class MapStage extends React.Component { this.setState({mouseX: mousePos.x, mouseY: mousePos.y}); } - dragBoundFunc(pos) { + handleShortcuts(action) { + switch (action) { + case "MOVE_LEFT": + this.moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0); + break; + case "MOVE_RIGHT": + this.moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0); + break; + case "MOVE_UP": + this.moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT); + break; + case "MOVE_DOWN": + this.moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT); + break; + default: + break; + } + } + + moveWithDelta(deltaX, deltaY) { const updatedPosition = { - x: pos.x > 0 ? 0 : - (pos.x < -MAP_SIZE_IN_PIXELS + this.state.width ? -MAP_SIZE_IN_PIXELS + this.state.width : pos.x), - y: pos.y > 0 ? 0 : - (pos.y < -MAP_SIZE_IN_PIXELS + this.state.height ? -MAP_SIZE_IN_PIXELS + this.state.height : pos.y) + x: this.state.x + deltaX > 0 ? 0 : + (this.state.x + deltaX < -MAP_SIZE_IN_PIXELS + this.state.width + ? -MAP_SIZE_IN_PIXELS + this.state.width : this.state.x + deltaX), + y: this.state.y + deltaY > 0 ? 0 : + (this.state.y + deltaY < -MAP_SIZE_IN_PIXELS + this.state.height + ? -MAP_SIZE_IN_PIXELS + this.state.height : this.state.y + deltaY) }; this.setState(updatedPosition); @@ -54,24 +76,28 @@ class MapStage extends React.Component { render() { return ( - <Stage ref={(stage) => {this.stage = stage;}} - width={this.state.width} - height={this.state.height} - onMouseMove={this.updateMousePosition.bind(this)}> - <Layer> - <Group draggable={true} dragBoundFunc={this.dragBoundFunc.bind(this)}> - <Backdrop/> - <DatacenterContainer/> - <GridGroup/> - </Group> - </Layer> - <HoverTileLayer - mainGroupX={this.state.x} - mainGroupY={this.state.y} - mouseX={this.state.mouseX} - mouseY={this.state.mouseY} - /> - </Stage> + <Shortcuts name="MAP" handler={this.handleShortcuts.bind(this)} targetNodeSelector="body"> + <Stage + ref={(stage) => {this.stage = stage;}} + width={this.state.width} + height={this.state.height} + onMouseMove={this.updateMousePosition.bind(this)} + > + <Layer> + <Group x={this.state.x} y={this.state.y}> + <Backdrop/> + <DatacenterContainer/> + <GridGroup/> + </Group> + </Layer> + <HoverTileLayer + mainGroupX={this.state.x} + mainGroupY={this.state.y} + mouseX={this.state.mouseX} + mouseY={this.state.mouseY} + /> + </Stage> + </Shortcuts> ) } } diff --git a/src/components/modals/Modal.js b/src/components/modals/Modal.js index 193746b3..6eebfb6e 100644 --- a/src/components/modals/Modal.js +++ b/src/components/modals/Modal.js @@ -42,6 +42,9 @@ class Modal extends React.Component { if (this.visible) { this.props.onCancel(); } + }) + .on("keydown", e => { + e.stopPropagation(); }); } diff --git a/src/components/sidebars/topology/NameComponent.js b/src/components/sidebars/topology/NameComponent.js new file mode 100644 index 00000000..d663f4ae --- /dev/null +++ b/src/components/sidebars/topology/NameComponent.js @@ -0,0 +1,13 @@ +import React from "react"; +import FontAwesome from "react-fontawesome"; + +const NameComponent = ({name, onEdit}) => ( + <h2> + {name} + <button className="btn btn-outline-secondary float-right" onClick={onEdit}> + <FontAwesome name="pencil"/> + </button> + </h2> +); + +export default NameComponent; diff --git a/src/components/sidebars/topology/room/RoomNameComponent.js b/src/components/sidebars/topology/room/RoomNameComponent.js index 4a8de76d..4d3e41cc 100644 --- a/src/components/sidebars/topology/room/RoomNameComponent.js +++ b/src/components/sidebars/topology/room/RoomNameComponent.js @@ -1,13 +1,8 @@ import React from "react"; -import FontAwesome from "react-fontawesome"; +import NameComponent from "../NameComponent"; const RoomNameComponent = ({roomName, onEdit}) => ( - <h2> - {roomName} - <button className="btn btn-outline-secondary float-right" onClick={onEdit}> - <FontAwesome name="pencil"/> - </button> - </h2> + <NameComponent name={roomName} onEdit={onEdit}/> ); export default RoomNameComponent; diff --git a/src/components/sidebars/topology/room/RoomSidebarComponent.js b/src/components/sidebars/topology/room/RoomSidebarComponent.js index 5ee9821a..dc01a301 100644 --- a/src/components/sidebars/topology/room/RoomSidebarComponent.js +++ b/src/components/sidebars/topology/room/RoomSidebarComponent.js @@ -1,8 +1,20 @@ import React from "react"; import RoomNameContainer from "../../../../containers/sidebars/topology/room/RoomNameContainer"; +import RoomTypeContainer from "../../../../containers/sidebars/topology/room/RoomTypeContainer"; const RoomSidebarComponent = ({roomType}) => { - return <RoomNameContainer/> + let allowedObjects; + if (roomType === "SERVER") { + allowedObjects = "test"; + } + + return ( + <div> + <RoomNameContainer/> + <RoomTypeContainer/> + {allowedObjects} + </div> + ); }; export default RoomSidebarComponent; diff --git a/src/components/sidebars/topology/room/RoomTypeComponent.js b/src/components/sidebars/topology/room/RoomTypeComponent.js new file mode 100644 index 00000000..c48c185a --- /dev/null +++ b/src/components/sidebars/topology/room/RoomTypeComponent.js @@ -0,0 +1,10 @@ +import React from "react"; +import {ROOM_TYPE_TO_NAME_MAP} from "../../../../util/room-types"; + +const RoomTypeComponent = ({roomType}) => ( + <p className="lead"> + {ROOM_TYPE_TO_NAME_MAP[roomType]} + </p> +); + +export default RoomTypeComponent; diff --git a/src/containers/sidebars/topology/room/RoomTypeContainer.js b/src/containers/sidebars/topology/room/RoomTypeContainer.js new file mode 100644 index 00000000..392bc479 --- /dev/null +++ b/src/containers/sidebars/topology/room/RoomTypeContainer.js @@ -0,0 +1,14 @@ +import {connect} from "react-redux"; +import RoomTypeComponent from "../../../../components/sidebars/topology/room/RoomTypeComponent"; + +const mapStateToProps = state => { + return { + roomType: state.objects.room[state.interactionLevel.roomId].roomType, + }; +}; + +const RoomNameContainer = connect( + mapStateToProps +)(RoomTypeComponent); + +export default RoomNameContainer; diff --git a/src/pages/App.js b/src/pages/App.js index 7f690002..98e2eac3 100644 --- a/src/pages/App.js +++ b/src/pages/App.js @@ -1,23 +1,36 @@ import PropTypes from "prop-types"; import React from 'react'; import {connect} from "react-redux"; +import {ShortcutManager} from "react-shortcuts"; import {openSimulationSucceeded} from "../actions/simulations"; import {fetchLatestDatacenter} from "../actions/topology"; import MapStage from "../components/map/MapStage"; import AppNavbar from "../components/navigation/AppNavbar"; import EditRoomNameModal from "../containers/modals/EditRoomNameModal"; import TopologySidebar from "../containers/sidebars/topology/TopologySidebar"; +import KeymapConfiguration from "../shortcuts/keymap"; + +const shortcutManager = new ShortcutManager(KeymapConfiguration); class AppContainer extends React.Component { static propTypes = { simulationId: PropTypes.number.isRequired, }; + static childContextTypes = { + shortcuts: PropTypes.object.isRequired + }; componentDidMount() { this.props.storeSimulationId(this.props.simulationId); this.props.fetchLatestDatacenter(); } + getChildContext() { + return { + shortcuts: shortcutManager + } + } + render() { return ( <div className="page-container full-height"> diff --git a/src/shortcuts/keymap.js b/src/shortcuts/keymap.js new file mode 100644 index 00000000..75986557 --- /dev/null +++ b/src/shortcuts/keymap.js @@ -0,0 +1,10 @@ +const KeymapConfiguration = { + MAP: { + MOVE_LEFT: ["a", "left"], + MOVE_RIGHT: ["d", "right"], + MOVE_UP: ["w", "up"], + MOVE_DOWN: ["s", "down"], + }, +}; + +export default KeymapConfiguration; diff --git a/src/util/room-types.js b/src/util/room-types.js new file mode 100644 index 00000000..ec0c4473 --- /dev/null +++ b/src/util/room-types.js @@ -0,0 +1,7 @@ +export const ROOM_TYPE_TO_NAME_MAP = { + "SERVER": "Server room", + "HALLWAY": "Hallway", + "OFFICE": "Office", + "POWER": "Power room", + "COOLING": "Cooling room", +}; |
