summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgios Andreadis <g.andreadis@student.tudelft.nl>2017-09-03 17:53:03 +0200
committerGeorgios Andreadis <g.andreadis@student.tudelft.nl>2017-09-23 10:05:56 +0200
commit81e517002bfdfbcd75109c562d890a27d190889b (patch)
treed69171040b5b9bfd45bfa4a51427a2138ffe9ea4
parent17ae0a3fafd806a5a533bf1d51a3ac708a8cf978 (diff)
Convert map movement to keyboard-based navigation
-rw-r--r--package.json1
-rw-r--r--src/components/map/MapConstants.js2
-rw-r--r--src/components/map/MapStage.js74
-rw-r--r--src/components/modals/Modal.js3
-rw-r--r--src/components/sidebars/topology/NameComponent.js13
-rw-r--r--src/components/sidebars/topology/room/RoomNameComponent.js9
-rw-r--r--src/components/sidebars/topology/room/RoomSidebarComponent.js14
-rw-r--r--src/components/sidebars/topology/room/RoomTypeComponent.js10
-rw-r--r--src/containers/sidebars/topology/room/RoomTypeContainer.js14
-rw-r--r--src/pages/App.js13
-rw-r--r--src/shortcuts/keymap.js10
-rw-r--r--src/util/room-types.js7
12 files changed, 138 insertions, 32 deletions
diff --git a/package.json b/package.json
index 25d27b02..5e71fcf9 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"react-redux": "^5.0.5",
"react-router-dom": "^4.1.1",
"react-scripts": "^1.0.11",
+ "react-shortcuts": "^1.6.1",
"redux": "^3.7.2",
"redux-localstorage": "^0.4.1",
"redux-logger": "^3.0.6",
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",
+};