ADD: added react-router and updated structure of app

This commit is contained in:
Henry Winkel
2023-11-03 12:35:43 +01:00
parent f926604c7f
commit 3e95bc2633
29 changed files with 950 additions and 798 deletions

View File

@@ -0,0 +1,220 @@
import React, { Component } from "react";
import {w3cwebsocket as W3CWebSocket} from "websocket"
// import Header from './components/Header';
import Controls from "./components/control/controls";
import OpenSeaMap from "./components/OpenSeaMap/OpenSeaMap";
const config = {
// apiUrl: process.env.REACT_APP_WEBAPP_WS_URL,
apiUrl: "192.168.3.13",
apiProt: 30747
}
const client = new W3CWebSocket("ws://"+config.apiUrl+":"+config.apiProt+"/");
class SimControl extends Component {
state = {
Entities: [],
EntityOnFocus: undefined,
PositionClicked: undefined
}
componentDidMount() {
console.log(config.apiUrl);
client.onopen = () => {
console.log("Websocket Client for Map Connected");
};
client.onmessage = (message) => {
const dataFromServer = JSON.parse(message.data);
// console.log('reply: ', dataFromServer);
if(dataFromServer.Data === "COP")
{
if(dataFromServer.Entities === undefined)
{
dataFromServer.Entities = [];
}
// console.log(this.state.EntityOnFocus);
let tmp = new Array(); ;
if(this.state.Entities !== undefined && this.state.Entities.length !== 0){
if(dataFromServer.Entities.length > 0)
{
dataFromServer.Entities.forEach((elementFromWS, indexWS) => {
if (this.isStored(elementFromWS.id) !== true)
{
tmp.push(elementFromWS);
}
this.state.Entities.forEach((elementStored, indexStore) => {
if(elementFromWS.id === elementStored.id)
{
// console.log(elementStored);
if(elementStored.onFocus !==true | elementStored.onFocus === undefined)
{
tmp.push(elementFromWS);
}else
{
tmp.push(elementStored);
}
}else{
// console.log(elementFromWS);
// tmp.push(elementFromWS);
}
});
});
}
}else{
tmp = dataFromServer.Entities;
}
// console.log(tmp);
this.setState((state) => ({
// Entities: structuredClone(dataFromServer.Entities)
Entities: structuredClone(tmp)
})
)
}
}
/// interval for updates
setInterval(() => {
this.updateEntities();
}, 2000);
}
isStored(id) {
var found = false;
this.state.Entities.forEach((elementStored, indexStore) => {
if (id === elementStored.id)
{
found = true;
}
});
return found;
}
updateEntities()
{
var msg =
{
Type: "Request",
Data: "COP"
}
client.send(JSON.stringify(msg));
}
getEntityFromID(Entities, SelectedEntity)
{
// console.log(Entities);
}
setEntityOnFocus(Entity)
{
if(Entity === undefined)
{
this.resetEntityOnFocus();
return;
}
this.getEntityFromID(this.state.Entities,Entity)
console.log(Entity);
this.setState({
EntityOnFocus: Entity
});
this.state.Entities.forEach((element, index) => {
// console.log(element);
if(element.id === Entity.EntityID)
{
var tmpList = structuredClone(this.state.Entities);
tmpList[index].onFocus = true;
if(Entity.NewPos !== undefined)
{
tmpList[index].Position = Entity.NewPos
}
this.setState({
Entities: structuredClone(tmpList)
});
if(Entity.dragged !== undefined)
{
if(Entity.dragged === true)
{
tmpList[index].dragged = true;
}
}
console.log(tmpList[index]);
}
});
}
resetEntityOnFocus()
{
if(this.state.EntityOnFocus !== undefined)
{
this.state.Entities.map((element ,index) => {
if(element.id === this.state.EntityOnFocus.EntityID)
{
this.state.Entities[index].onFocus = false;
}
})
console.log(this.state.Entities)
this.setState({
EntityOnFocus: undefined
})
}
}
setFocusPosition(props)
{
// console.log(Entity);
this.setState({
PositionClicked: props
});
}
Functions = {
updateEntities: this.updateEntities.bind(this),
resetEntityOnFocus: this.resetEntityOnFocus.bind(this)
}
render() {
const {name} = this.state;
return (
<div className="App">
<div className="Content">
<Controls Functions= {this.Functions} Client= {client} Entities= {this.state.Entities} updateEntities = {this.updateEntities} EntityOnFocus = {this.state.EntityOnFocus} PositionClicked = {this.state.PositionClicked} />
<OpenSeaMap Entities= {this.state.Entities} Client= {client} updateEntities = {this.updateEntities} setEntityOnFocus = {this.setEntityOnFocus.bind(this)} setFocusPosition = {this.setFocusPosition.bind(this)}/>
</div>
</div>
);
}
}
export default SimControl;

View File

@@ -0,0 +1,4 @@
import OpenSeaMap from "./OpenSeaMap.jsx.js";
export default OpenSeaMap;

View File

@@ -0,0 +1,242 @@
// import { useMapEvents } from 'react-leaflet/hooks'
import React, { Component } from "react";
import { MapContainer, TileLayer,Marker, Popup, Tooltip,useMapEvents,contextmenu } from 'react-leaflet'
import { friend,Hostile, iconShip,createIcon } from "./icon";
import "./OpenSeaMap.scss";
import {w3cwebsocket as W3CWebSocket} from "websocket";
// import ContainerDimensions from 'react-container-dimensions';
import {} from "leaflet-contextmenu";
class OpenSeaMap extends Component {
state = {
EntityOnFocus: undefined,
}
updateDimensions() {
const height = window.innerWidth >= 950 ? window.innerHeight : 400
this.setState({ height: height })
}
componentWillMount() {
this.updateDimensions()
}
componentDidMount() {
window.addEventListener("resize", this.updateDimensions.bind(this))
console.log(this.state.EntityOnFocus);
}
componentWillUnmount() {
window.removeEventListener("resize", this.updateDimensions.bind(this))
}
handleClick(e)
{
// console.log(e.target)
// this.setState({ currentPos: e.latlng });
// console.log(e.latlng);
// console.log("hello world");
}
markerOnClick(e) {
console.log(e);
}
setOnFocus(e)
{
console.log(e.relatedTarget);
e.relatedTarget.dragging.enable();
e.relatedTarget.options.draggable = true;
var Ent = {
EntityID : e.relatedTarget.options.data,
NewPos : undefined
}
this.setState((state) =>({
EntityOnFocus: Ent
}))
this.props.setEntityOnFocus(Ent)
// this.draggable = true;
}
makeIcon(index, entity,props,state)
{
var isOnFocus = false;
if(this.state.EntityOnFocus !== undefined){
// console.log(entity.id+ " " , this.state.EntityOnFocus);
// console.log(props+ " " , this.state.EntityOnFocus);
if(entity.id === this.state.EntityOnFocus.EntityID)
{
isOnFocus = true
// if(this.state.EntityOnFocus.NewPos !== undefined)
// {
// entity.pos = this.state.EntityOnFocus.NewPos;
// }
}
}
var icon;
icon = createIcon(entity.Type,entity.Side)
return (
<Marker name={entity.Name} key={index} icon={icon} position={entity.Position} data={entity.id}
draggable={isOnFocus? true : false}
contextmenu={true}
contextmenuWidth={140}
contextmenuItems={[{
text:"Edit",
index:0,
callback: this.setOnFocus.bind(this),
},{
text:"Delete",
index: 1,
callback: function() {
var msg =
{
Data: "Entity",
Type: "Delete",
ID: entity.id,
}
console.log(JSON.stringify(msg));
state.EntityOnFocus = undefined;
props.setEntityOnFocus(undefined)
props.Client.send(JSON.stringify(msg))
},
// separator: true,
}, {
text:"Test",
callback: this.markerOnClick.bind(this),
// separator: true,
index: 2
}, {
text:"Exit",
callback: function()
{
state.EntityOnFocus = undefined;
props.setEntityOnFocus(undefined);
},
// separator: true,
index: 3
}]}
// contextmenuItems: [{
// text: 'Circle 1',
// callback: function() {
// circleContextClick(circle1);
// }
// }]
eventHandlers={{
click: (e) => {
// console.log(e.target);
// var Ent = {
// EntityID : e.target.options.data,
// NewPos : undefined
// }
// this.setState((state) =>({
// EntityOnFocus: Ent
// }))
// this.props.setEntityOnFocus(Ent);
// this.props.setEntityOnFocus(e.target.options.data);
},
dragend: (e) =>
{
var Ent = {
EntityID : e.target.options.data,
NewPos : [e.target._latlng.lat,e.target._latlng.lng],
dragged: true
}
this.setState((state) =>({
EntityOnFocus: Ent
}))
this.props.setEntityOnFocus(Ent);
// console.log(e.target);
// console.log(e.target._latlng);
},
// contextmenu: (e) =>
// {
// console.log("right click");
// }
}}
// eventHandlers={this.MarkerEventHandler}
>
{/* <Popup>
Omu-Aran the Head Post of Igbomina land,
is a town in the Nigerian state of Kwara.
It originated from Ife and currently the local
government headquarters of Irepodun local government.
</Popup> */}
<Tooltip direction='bottom' offset={[0,13]} opacity={1} permanent>
<span>{entity.Name}</span>
</Tooltip>
</Marker>
);
}
setPos(props)
{
console.log(props);
this.props.setFocusPosition([1,2])
}
render() {
const LocationFinderDummy = (props) => {
const map = useMapEvents({
click(e) {
props.props.setFocusPosition(e.latlng)
// console.log(e.latlng);
},
});
return null;
};
// const positions = this.props.Positions.map((pos, index) => (
// <Marker name={"test"} key={index} position={pos.position} icon= {ship} />
// ));
return (
<div className='map' style={{ height: this.state.height }} >
<MapContainer center={[54, 11]} zoom={6} scrollWheelZoom={true} contextmenu={false}
>
<LocationFinderDummy props ={this.props} />
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
<TileLayer
url="https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png" />
{/* {positions} */}
{this.props.Entities.map((pos, index) => (
this.makeIcon(index,pos,this.props,this.state)
))}
</MapContainer>
</div>
);
}
}
export default OpenSeaMap;

View File

@@ -0,0 +1,23 @@
@import 'leaflet/dist/leaflet.css';
// @import url('https://unpkg.com/leaflet@1.5.1/dist/leaflet.css');
.leaflet-container {
width: 100%;
height: 90%;
}
.map {
// display: flex;
padding-top: 10px;
// height: 750px;
width: 72%;
// padding-left: 20%;
display: inline-flex;
// height: 80%;
}
// .leaflet-marker-icon{
// background: red;
// }

View File

@@ -0,0 +1,96 @@
import { Icon} from 'leaflet';
import ms from 'milsymbol'
const iconShip = new Icon({
iconUrl: "./ship.svg",
iconSize: [50, 50],
// iconAnchor: [40, 90],
popupAnchor: [-25, -40],
});
const HostileLetter = "H";
const FriendLetter = "F";
const NeutralLetter = "N";
const AirLetter = "A";
const SurfaceLetter = "S";
const SubsurfaceLetter = "U";
// const Size = 25;
function createIcon(Type , Side )
{
var TypeLetter = "S";
var SideLetter = "N";
switch (Side) {
case "Hostile":
SideLetter = HostileLetter;
break;
case "Friend":
SideLetter = FriendLetter;
break;
case "Neutral":
SideLetter = NeutralLetter;
break;
default:
SideLetter = "N";
break;
}
switch (Type) {
case "Air":
TypeLetter = AirLetter;
break;
case "Surface":
TypeLetter = SurfaceLetter;
break;
case "Subsurface":
TypeLetter = SubsurfaceLetter;
break;
default:
TypeLetter = "S";
break;
}
var IconS = new ms.Symbol(
"S"+SideLetter+TypeLetter+"*"+"--------"
)
IconS = IconS.setOptions({ size: 25 });
var Symbol = new Icon({
iconUrl: IconS.toDataURL(),
iconAnchor: [IconS.getAnchor().x, IconS.getAnchor().y],
})
return Symbol
}
var Friend = new ms.Symbol(
"SFS*--------", {
// uniqueDesignation: "Friend"
})
// Now that we have a symbol we can ask for the echelon and set the symbol size
Friend = Friend.setOptions({ size: 25 });
const friend = new Icon({
iconUrl: Friend.toDataURL(),
iconAnchor: [Friend.getAnchor().x, Friend.getAnchor().y],
});
var hostile = new ms.Symbol(
"SHU*---------", {
uniqueDesignation: "Hostile"
})
// Now that we have a symbol we can ask for the echelon and set the symbol size
hostile = hostile.setOptions({ size: 25 });
const Hostile = new Icon({
iconUrl: hostile.toDataURL(),
iconAnchor: [hostile.getAnchor().x, hostile.getAnchor().y],
});
export { iconShip, friend,Hostile,createIcon };

View File

@@ -0,0 +1,392 @@
import React from "react"
import {useState,useEffect, useRef} from 'react';
import { useForm, SubmitHandler } from "react-hook-form"
import Form from 'react-bootstrap/Form';
import FloatingLabel from 'react-bootstrap/FloatingLabel';
import InputGroup from 'react-bootstrap/InputGroup';
import round from "../../../Utils";
import 'bootstrap/dist/css/bootstrap.min.css';
import './controls.css'
function EntityControl(props)
{
const RoundPrecision = 2;
const RoundPrecisionPosition = 4;
const [Entity, setEntity] = useState(undefined);
// const [Course, setCourse] = useState('');
const [PositionDragged, setPositionDragged] = useState(false);
// const [Speed, setSpeed] = useState();
const [formData, setFormData] = useState({name: "",course: 0 ,speed: 0,position: [0,0],height:0});
useEffect(() => { // Update the document title using the browser API document.title = `You clicked ${count} times`;
// console.log(props.Entity);
if(props.Entity !== undefined)
{
// console.log(props.Entity)
if(Entity === undefined)
{
setEntity(props.Entity);
setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision) })
}else if(Entity.id !== props.Entity.id)
{
setEntity(props.Entity);
setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
} else if(Entity.id === props.Entity.id && Entity.Position !== props.Entity.Position)
{
setFormData({...formData,position:props.Entity.Position,height:round(props.Entity.Height,RoundPrecision)})
setPositionDragged(true);
}
// setFormData({name:props.Entity.Name,course:props.Entity.Course,speed:props.Entity.Speed,position:props.Entity.Position})
}
},[props.Entity,props]);
useEffect(() => {
if(props.PositionCliecked !== undefined)
{
console.log(props.PositionCliecked)
var pos = [0,0];
pos[0] = props.PositionCliecked.lat;
pos[1] = props.PositionCliecked.lng
setFormData({...formData,position:pos});
}
},[props.PositionCliecked])
// Entity.Entity.Course
const handleClick = (e) => {
if(e.detail === 2)
{
console.log(e)
// setCourseInControl(true);
e.target.readOnly = false;
// e.target.style = "border: 1px solid"
}
};
const handleCourseInput= (e) => {
// console.log(e.currentTarget.value)
// console.log(isNaN(e.nativeEvent?.data))
// if(!isNaN(e.nativeEvent?.data))
if(Number.isInteger(parseFloat(e.currentTarget.value)) | e.nativeEvent?.data === null )
{
setFormData({...formData,course:e.currentTarget.value});
if(props.Entity !== undefined)
{
props.Entity.Course = e.currentTarget.value.replace(",",".");
}
}
// if(e.currentTarget.value === "")
// {
// setFormData({...formData,course:0});
// props.Entity.Course = 0;
// }
};
const handleSpeedInput= (e) => {
// console.log(e.nativeEvent?.data)
// if(!isNaN(e.nativeEvent?.data))
if(Number.isInteger(parseFloat(e.currentTarget.value)) | e.nativeEvent?.data === null )
{
setFormData({...formData,speed:e.currentTarget.value});
if(props.Entity !== undefined)
{
props.Entity.Speed = e.currentTarget.value.replace(",",".");
}
}
// if(e.nativeEvent?.data == null)
// {
// setFormData({...formData,speed:0});
// props.Entity.Speed = 0;
// }
// console.log(formData.speed)
};
const handleNameInput = (e) => {
setFormData({...formData,name:e.currentTarget.value});
}
const handleInput = (e) => {
// console.log(e.target.name)
switch (e.target.name) {
case "Lat":
if(Number.isInteger(parseFloat(e.currentTarget.value)) | e.nativeEvent?.data === null)
{
// e.currentTarget.value = e.currentTarget.value.replace(",",".");
setFormData({...formData,position:[e.currentTarget.value,formData.position[1],formData.position[2]] });
}
if(props.Entity !== undefined)
{
props.Entity.Position[0]=e.currentTarget.value.replace(",",".");
}
break;
case "Lon":
if(Number.isInteger(parseFloat(e.currentTarget.value)) | e.nativeEvent?.data === null)
{
setFormData({...formData,position:[formData.position[0],e.currentTarget.value,formData.position[2]] });
if(props.Entity !== undefined)
{
props.Entity.Position[1]=e.currentTarget.value.replace(",",".");
}
}
// else if(e.nativeEvent?.data == null) {
// // setFormData({...formData,position:[formData.position[0],0,formData.position[2]] });
// }
break;
case "Height":
setFormData({...formData,height:e.currentTarget.value.replace(",",".")});
if(props.Entity !== undefined)
{
props.Entity.Height=e.currentTarget.value.replace(",",".");
}
break;
default:
break;
}
setPositionDragged(true);
}
const emptyForm= (e) =>
{
if(props.Entity !== undefined)
{
props.Entity.onFocus = undefined;
}
setFormData({name:'',course:0,speed:0,position:[0,0],height:0})
setEntity(undefined)
props.Functions.resetEntityOnFocus();
}
const resetForm = (e)=>
{
if(props.Entity !== undefined)
{
console.log("resetting")
setFormData({name:props.Entity.Name,course:Entity.Course,speed:Entity.Speed,position:Entity.Position})
props.Entity.Position = Entity.Position;
props.Entity.Course = Entity.Course;
props.Entity.Speed = Entity.Speed;
}
else {
emptyForm();
}
}
// const handleChange = (event) => {
// const { name, value } = event.target;
// setFormData((prevFormData) => ({ ...prevFormData, [name]: value }));
// };
const handleSubmit = (e) => {
e.preventDefault();
// console.log(e.target.data);
// console.log(formData)
console.log(Entity)
if(Entity === undefined)
{
var msg =
{
Data: "Entity",
Type: "New",
Name: formData.name,
Speed: formData.speed.toString(),
Course: formData.course.toString(),
Position: [formData.position[0].toString(),formData.position[1].toString()],
Height: formData.height.toString(),
SetPosition: true
}
}else {
var setPos;
if(PositionDragged === true)
{
setPos = true;
}else{
setPos = false;
}
var msg =
{
Data: "Entity",
Type: "Update",
ID: Entity.id,
Speed: formData.speed.toString(),
Course: formData.course.toString(),
Position: [formData.position[0].toString(),formData.position[1].toString()],
Height: formData.height.toString(),
SetPosition: setPos
}
}
console.log(JSON.stringify(msg));
props.Client.send(JSON.stringify(msg));
// alert(`Course: ${formData.course}`);
}
// console.log(Entity)
// console.log(EntityOnFocus)
return (
<div>
<div><button onClick={ emptyForm}> New</button> </div>
<form onSubmit={handleSubmit}>
<div className="ControlsComponent">
<div class="parent">
<div class="div1">
<div className="ControlLineHeader">
<InputGroup className="mb-3">
<InputGroup.Text id="basic-addon1">Kind</InputGroup.Text>
<Form.Select name="Kind" size="sm" >
<option selected value="plattform"> Plattform</option>
</Form.Select>
</InputGroup>
</div>
</div>
<div class="div2">
<div className="ControlLineHeader">
{/* <div className="LineHeader">Domain:</div>
<select name="domain">
<option name="surface">Surface</option>
</select> */}
<InputGroup className="mb-3">
<InputGroup.Text id="basic-addon1">Domain</InputGroup.Text>
<Form.Select name="Domain" >
<option selected value="Surface"> Surface</option>
</Form.Select>
</InputGroup>
</div>
</div>
<div class="div3">
<InputGroup className="mb-3">
<InputGroup.Text id="basic-addon1">Type</InputGroup.Text>
<Form.Select name="Domain" >
<option selected value="F124"> F124</option>
</Form.Select>
</InputGroup>
</div>
<div class="div4">
<InputGroup className="mb-3">
<InputGroup.Text id="basic-addon1">Name</InputGroup.Text>
<Form.Control
name="Name"
placeholder="Name"
aria-label="Name"
aria-describedby="basic-addon1"
value={formData.name}
onChange={handleNameInput}
/>
{/* <input name="Name" type="text" onChange={handleNameInput} value={formData.name} /> */}
</InputGroup>
{/* <div class="NameInput">
<div className="ControlLineHeader">Name:</div>
</div> */}
</div>
<div class="div5">
<div class="input-group mb-3">
<span class="input-group-text">Course</span>
<input className="EntityinputField" name="Course" readOnly={false} type="text" onClick={handleClick} onChange={handleCourseInput} value={formData.course} />
</div>
</div>
<div class="div6">
<div class="input-group mb-3">
<span class="input-group-text">Speed</span>
<input className="EntityinputField" name="Speed" onChange={handleSpeedInput} value={formData.speed} />
</div>
</div>
<div class="div7">
<div class="input-group mb-3 NumberInputsGroup">
<span class="input-group-text">Lat</span>
<input className="ControlInput NumberInputs" name="Lat" type="text" onChange={handleInput} value={round(formData.position[0],RoundPrecisionPosition)} />
</div>
</div>
<div class="div8">
<div class="input-group mb-3 NumberInputsGroup" >
<span class="input-group-text">Lon</span>
{/* <input className="ControlInput" name="Lat" readOnly={true} type="text" onClick={handleClick} value={formData.position[0]} /> */}
<input className="ControlInput NumberInputs" name="Lon" readOnly={true} type="text" onClick={handleClick} onChange={handleInput} value={round(formData.position[1],RoundPrecisionPosition)}/>
</div>
{/* <div className="flex">
<div className="ControlHeader">Lon:</div>
</div> */}
</div>
<div class="div9">
<div class="input-group mb-3 NumberInputsGroup">
<span class="input-group-text">Height</span>
{/* <input className="ControlInput" name="Lat" readOnly={true} type="text" onClick={handleClick} value={formData.position[0]} /> */}
<input className="ControlInput NumberInputs" name="Height" readOnly={true} type="text" onClick={handleClick} onChange={handleInput} value={formData.height}/>
</div>
{/* <div className="ControlHeader">Height:</div>
<div className="flex">
</div> */}
</div>
</div>
<div> <button type='submit'>Save</button> </div>
</div>
</form>
<button onClick={resetForm}> RESET</button>
</div>
);
}
export default EntityControl;

View File

@@ -0,0 +1,3 @@
import Tracklist from "./tracklist.jsx";
export default Tracklist;

View File

@@ -0,0 +1,52 @@
import React from 'react';
import './tracklist.scss'
import round from '../../../../Utils';
class Tracklist extends React.Component
{
render()
{
return(
<div className="tracklist">
<table>
<thead>
<tr className='TracklistHeader'>
<th className='TracklistHeaderCell'>Name</th>
<th className='TracklistHeaderCell'>Course</th>
<th className='TracklistHeaderCell'>Speed</th>
<th className='TracklistHeaderCell'>Lat</th>
<th className='TracklistHeaderCell'>Lon</th>
<th className='TracklistHeaderCell'>Kind</th>
<th className='TracklistHeaderCell'>Side</th>
</tr>
</thead>
<tbody>
{ this.props.entities.map((val,index) => {
return (
<tr key={index}>
<td >{val.Name}</td>
<td className='TracklistCell'>{val.Course}</td>
<td className='TracklistCell'>{val.Speed}</td>
<td className='TracklistCell'>{round(val.Position[0],4)}</td>
<td className='TracklistCell'>{round(val.Position[1],4)}</td>
<td className='TracklistCell'>{val.Type}</td>
<td className='TracklistCell'>{val.Side}</td>
</tr>
)
})}
</tbody>
</table>
</div>
);
}
}
export default Tracklist;

View File

@@ -0,0 +1,40 @@
.tracklist
{
display: flex;
max-height: 40%;
height: 300px;
display: block;
}
td
{
text-align: left;
}
.TracklistHeader {
border-bottom: 2px solid;
}
table {
border-collapse: collapse;
}
th{
// border: 1px solid;
// border-collapse: collapse;
}
.TracklistCell{
border-left: 1px solid;
text-align: center;
}
.TracklistHeaderCell{
width: 16%;
}
// table, th, td {
// border: 1px solid;
// border-collapse: collapse;
// }

View File

@@ -0,0 +1,91 @@
.controls{
/* display: flex; */
width: 24%;
float: left;
}
.ControlsComponent{
display: grid;
/* grid-template-columns: auto auto auto; */
}
.ControlInput{
/* border: none; */
width: 30%;
}
.NameInput{
/* margin: 0 auto; */
display: flex;
}
.EntityinputField{
/* border: none; */
width: 30%;
display: flex;
}
.flex{
display: flex !important;
}
.ControlHeader{
float: left;
width: 50%;
}
.ControlLineHeader
{
float: left;
width: 100%;
}
.LineHeader{
display: flex;
float: left;
}
.sizedSelect{
width: 50% !important;
}
.NumberInputs{
width: 4.3em;
}
.NumberInputsGroup
{
flex-wrap: inherit !important;
}
.ControlValues{
float: left;
display: contents;
}
/* .parent {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(3 2em);
grid-column-gap: 0px;
grid-row-gap: 0px;
}
.div1 { grid-area: 1 / 1 / 2 / 3; }
.div2 { grid-area: 2 / 1 / 3 / 2; }
.div3 { grid-area: 2 / 2 / 3 / 3; }
.div4 { grid-area: 3 / 2 / 4 / 3; }
.div5 { grid-area: 3 / 1 / 4 / 2; } */
.parent {
display: grid;
grid-template-columns: repeat(3, 2fr);
grid-template-rows: repeat(6, 3em);
grid-column-gap: 0px;
grid-row-gap: 0px3
}
.div1 { grid-area: 1 / 1 / 2 / 4; }
.div2 { grid-area: 2 / 1 / 3 / 4; }
.div3 { grid-area: 3 / 1 / 4 / 4; }
.div4 { grid-area: 4 / 1 / 5 / 4; }
.div5 { grid-area: 5 / 1 / 6 / 2; }
.div6 { grid-area: 5 / 2 / 6 / 3; }
.div7 { grid-area: 6 / 1 / 7 / 2; }
.div8 { grid-area: 6 / 2 / 7 / 3; }
.div9 { grid-area: 6 / 3 / 7 / 4; }

View File

@@ -0,0 +1,95 @@
import React from 'react';
import './controls.css'
// import { sendMsg } from '../api';
import Tracklist from './Tracklist'
import EntityControl from './EntityControl';
import round from '../../../Utils';
// import {w3cwebsocket as W3CWebSocket} from "websocket"
class Controls extends React.Component
{
state = {
EntityOnFocus: undefined,
}
componentDidMount()
{
if (this.props.Entities === undefined)
{
this.props.Entities = new Array();
}
}
render() {
function getEntityFromID(Entities, SelectedEntity)
{
if(SelectedEntity !== undefined)
{
var tmp = {};
// tmp.NewPos= new Array(0,0);
// console.log(tmp);
Entities.map((val) => {
if(val.id === SelectedEntity.EntityID)
{
tmp = val
// tmp = JSON.parse(JSON.stringify(val));
// console.log(tmp);
val.dragged = SelectedEntity.dragged;
if(SelectedEntity.dragged === undefined)
{
val.dragged = false;
}
// console.log(SelectedEntity);
// if(SelectedEntity.NewPos !== undefined)
// {
// // Object.assign(tmp, {NewPos: [{},{}]});
// Object.assign(val, {NewPos: [{},{}]});
// // tmp.OldPos = val.Position;
// // Object.assign(tmp, {NewPos: [round(SelectedEntity.NewPos[0],3),0]});
// // val.NewPos = SelectedEntity.NewPos;
// val.NewPos[0] = round(SelectedEntity.NewPos[0],3);
// val.NewPos[1] = round(SelectedEntity.NewPos[1],3);
// // tmp.NewPos[0] = round(SelectedEntity.NewPos[0],3);
// // tmp.NewPos[1] = round(SelectedEntity.NewPos[1],3);
// }
// tmp.NewPos = SelectedEntity.NewPos;
}
return tmp;
})
// console.log(tmp);
return tmp;
}
}
// console.log(getEntityFromID(this.props.Entities,this.props.EntityOnFocus));
return (
<div className="controls">
<Tracklist entities= {this.props.Entities} />
<br />
<div>
{/* <button onClick={this.props.updateEntities}>update</button> */}
<EntityControl Functions = {this.props.Functions} Client = { this.props.Client } Entity = { getEntityFromID(this.props.Entities,this.props.EntityOnFocus)} EntityOnFocus= {this.props.EntityOnFocus} PositionCliecked = {this.props.PositionClicked}/>
</div>
</div>
);
}
}
export default Controls;

View File

@@ -0,0 +1,3 @@
import Controls from "./controls.jsx";
export default Controls;

View File

@@ -0,0 +1,4 @@
.map
{
width: 70%;
}

View File

@@ -0,0 +1,16 @@
import React from 'react';
import './mapframe.css'
class Mapframe extends React.Component
{
render() {
return (
<div className="map">
this is the map frame
</div>
);
}
}
export default Mapframe;

View File

@@ -0,0 +1,3 @@
import SimControl from "./SimControl.jsx";
export default SimControl;