mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Added state and events context
This commit is contained in:
@@ -1,28 +1,142 @@
|
||||
import React from 'react'
|
||||
import { useState } from 'react'
|
||||
import './App.css'
|
||||
import './app.css'
|
||||
|
||||
import { MapContainer, TileLayer } from 'react-leaflet'
|
||||
|
||||
import { Map } from './map/map'
|
||||
import { Header } from './ui/header'
|
||||
import { EventsProvider } from './eventscontext'
|
||||
import { StateProvider } from './statecontext'
|
||||
|
||||
var map: Map;
|
||||
const position = [51.505, -0.09]
|
||||
|
||||
function App() {
|
||||
const [count, setCount] = useState(0)
|
||||
|
||||
return (
|
||||
<div style={{ width: "100%", height: "100%" }}>
|
||||
<MapContainer center={position} zoom={13} className='absolute w-full h-full top-0 left-0'>
|
||||
<TileLayer
|
||||
url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
|
||||
/>
|
||||
</MapContainer>
|
||||
<Header></Header>
|
||||
</div>
|
||||
)
|
||||
export type OlympusState = {
|
||||
spawnMenuVisible: boolean,
|
||||
unitControlMenuVisible: boolean,
|
||||
measureMenuVisible: boolean,
|
||||
drawingMenuVisible: boolean
|
||||
}
|
||||
|
||||
export default App
|
||||
export default class App extends React.Component<{}, OlympusState> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
/* State initialization */
|
||||
this.state = {
|
||||
spawnMenuVisible: false,
|
||||
unitControlMenuVisible: false,
|
||||
measureMenuVisible: false,
|
||||
drawingMenuVisible: false
|
||||
}
|
||||
|
||||
/* Methods bindings */
|
||||
this.showSpawnMenu = this.showSpawnMenu.bind(this);
|
||||
this.toggleSpawnMenu = this.toggleSpawnMenu.bind(this);
|
||||
this.showUnitControlMenu = this.showUnitControlMenu.bind(this);
|
||||
this.toggleUnitControlMenu = this.toggleUnitControlMenu.bind(this);
|
||||
this.showMeasureMenu = this.showMeasureMenu.bind(this);
|
||||
this.toggleMeasureMenu = this.toggleMeasureMenu.bind(this);
|
||||
this.showDrawingMenu = this.showDrawingMenu.bind(this);
|
||||
this.toggleDrawingMenu = this.toggleDrawingMenu.bind(this);
|
||||
}
|
||||
|
||||
showSpawnMenu(show: boolean) {
|
||||
this.setState({
|
||||
spawnMenuVisible: show,
|
||||
unitControlMenuVisible: false,
|
||||
measureMenuVisible: false,
|
||||
drawingMenuVisible: false
|
||||
});
|
||||
}
|
||||
|
||||
toggleSpawnMenu() {
|
||||
this.setState({
|
||||
spawnMenuVisible: !this.state.spawnMenuVisible,
|
||||
unitControlMenuVisible: false,
|
||||
measureMenuVisible: false,
|
||||
drawingMenuVisible: false
|
||||
});
|
||||
}
|
||||
|
||||
showUnitControlMenu(show: boolean) {
|
||||
this.setState({
|
||||
spawnMenuVisible: false,
|
||||
unitControlMenuVisible: show,
|
||||
measureMenuVisible: false,
|
||||
drawingMenuVisible: false
|
||||
});
|
||||
}
|
||||
|
||||
toggleUnitControlMenu() {
|
||||
this.setState({
|
||||
spawnMenuVisible: false,
|
||||
unitControlMenuVisible: !this.state.unitControlMenuVisible,
|
||||
measureMenuVisible: false,
|
||||
drawingMenuVisible: false
|
||||
});
|
||||
}
|
||||
|
||||
showMeasureMenu(show: boolean) {
|
||||
this.setState({
|
||||
spawnMenuVisible: false,
|
||||
unitControlMenuVisible: false,
|
||||
measureMenuVisible: show,
|
||||
drawingMenuVisible: false
|
||||
});
|
||||
}
|
||||
|
||||
toggleMeasureMenu() {
|
||||
this.setState({
|
||||
spawnMenuVisible: false,
|
||||
unitControlMenuVisible: false,
|
||||
measureMenuVisible: !this.state.measureMenuVisible,
|
||||
drawingMenuVisible: false
|
||||
});
|
||||
}
|
||||
|
||||
showDrawingMenu(show: boolean) {
|
||||
this.setState({
|
||||
spawnMenuVisible: false,
|
||||
unitControlMenuVisible: false,
|
||||
measureMenuVisible: false,
|
||||
drawingMenuVisible: show
|
||||
});
|
||||
}
|
||||
|
||||
toggleDrawingMenu() {
|
||||
this.setState({
|
||||
spawnMenuVisible: false,
|
||||
unitControlMenuVisible: false,
|
||||
measureMenuVisible: false,
|
||||
drawingMenuVisible: !this.state.drawingMenuVisible
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={{ width: "100%", height: "100%" }}>
|
||||
<StateProvider value={this.state}>
|
||||
<EventsProvider value={
|
||||
{
|
||||
showSpawnMenu: this.showSpawnMenu,
|
||||
toggleSpawnMenu: this.toggleSpawnMenu,
|
||||
showUnitControlMenu: this.showUnitControlMenu,
|
||||
toggleUnitControlMenu: this.toggleUnitControlMenu,
|
||||
showMeasureMenu: this.showMeasureMenu,
|
||||
toggleMeasureMenu: this.toggleMeasureMenu,
|
||||
showDrawingMenu: this.showMeasureMenu,
|
||||
toggleDrawingMenu: this.toggleDrawingMenu
|
||||
}
|
||||
}>
|
||||
<MapContainer center={position} zoom={13} className='absolute w-full h-full top-0 left-0'>
|
||||
<TileLayer
|
||||
url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
|
||||
/>
|
||||
</MapContainer>
|
||||
<Header ></Header>
|
||||
</EventsProvider>
|
||||
</StateProvider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
15
frontend/react/src/eventscontext.tsx
Normal file
15
frontend/react/src/eventscontext.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { createContext } from "react";
|
||||
|
||||
export const EventsContext = createContext({
|
||||
showSpawnMenu: (e: boolean) => {},
|
||||
toggleSpawnMenu: () => {},
|
||||
showUnitControlMenu: (e: boolean) => {},
|
||||
toggleUnitControlMenu: () => {},
|
||||
showMeasureMenu: (e: boolean) => {},
|
||||
toggleMeasureMenu: () => {},
|
||||
showDrawingMenu: (e: boolean) => {},
|
||||
toggleDrawingMenu: () => {}
|
||||
})
|
||||
|
||||
export const EventsProvider = EventsContext.Provider;
|
||||
export const EventsConsumer = EventsContext.Consumer;
|
||||
@@ -1,4 +1,4 @@
|
||||
@import "./leaflet/leaflet.css";
|
||||
@import "../node_modules/leaflet/dist/leaflet.css";
|
||||
|
||||
:root {
|
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import App from './App.tsx'
|
||||
import App from './app.tsx'
|
||||
import './index.css'
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
|
||||
12
frontend/react/src/statecontext.tsx
Normal file
12
frontend/react/src/statecontext.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import { createContext } from "react";
|
||||
import { OlympusState } from "./App";
|
||||
|
||||
export const StateContext = createContext({
|
||||
spawnMenuVisible: false,
|
||||
unitControlMenuVisible: false,
|
||||
measureMenuVisible: false,
|
||||
drawingMenuVisible: false
|
||||
} as OlympusState)
|
||||
|
||||
export const StateProvider = StateContext.Provider;
|
||||
export const StateConsumer = StateContext.Consumer;
|
||||
@@ -2,28 +2,34 @@ import React from 'react'
|
||||
import { StateButton } from './statebuttons';
|
||||
import { faPlus, faGamepad, faRuler, faPencil } from '@fortawesome/free-solid-svg-icons';
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import { EventsConsumer, EventsContext } from '../eventscontext';
|
||||
import { StateConsumer } from '../statecontext';
|
||||
|
||||
library.add(faPlus, faGamepad, faRuler, faPencil)
|
||||
|
||||
type HeaderProps = {
|
||||
export class Header extends React.Component<{}, {}> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type HeaderState = {
|
||||
|
||||
}
|
||||
|
||||
export class Header extends React.Component<HeaderProps, HeaderState> {
|
||||
render() {
|
||||
return (
|
||||
<div className='absolute top-0 left-0 h-16 w-full z-ui bg-background-steel flex flex-row items-center px-5'>
|
||||
<div className="flex flex-row items-center gap-1">
|
||||
<StateButton icon="fa-solid fa-plus"></StateButton>
|
||||
<StateButton icon="fa-solid fa-gamepad"></StateButton>
|
||||
<StateButton icon="fa-solid fa-ruler"></StateButton>
|
||||
<StateButton icon="fa-solid fa-pencil"></StateButton>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<StateConsumer>
|
||||
{(appState) =>
|
||||
<EventsConsumer>
|
||||
{(events) =>
|
||||
<div className='absolute top-0 left-0 h-16 w-full z-ui bg-background-steel flex flex-row items-center px-5'>
|
||||
<div className="flex flex-row items-center gap-1">
|
||||
<StateButton onClick={events.toggleSpawnMenu} active={appState.spawnMenuVisible} icon="fa-solid fa-plus"></StateButton>
|
||||
<StateButton onClick={events.toggleUnitControlMenu} active={appState.unitControlMenuVisible} icon="fa-solid fa-gamepad"></StateButton>
|
||||
<StateButton onClick={events.toggleMeasureMenu} active={appState.measureMenuVisible} icon="fa-solid fa-ruler"></StateButton>
|
||||
<StateButton onClick={events.toggleDrawingMenu} active={appState.drawingMenuVisible} icon="fa-solid fa-pencil"></StateButton>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</EventsConsumer>
|
||||
}
|
||||
</StateConsumer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import React from 'react'
|
||||
import React, { MouseEventHandler } from 'react'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { IconProp } from '@fortawesome/fontawesome-svg-core'
|
||||
|
||||
type ButtonProperties = {
|
||||
icon: string
|
||||
}
|
||||
|
||||
type ButtonState = {
|
||||
type ButtonProps = {
|
||||
icon: string,
|
||||
onClick: CallableFunction,
|
||||
active: boolean
|
||||
}
|
||||
|
||||
export class StateButton extends React.Component<ButtonProperties, ButtonState> {
|
||||
export class StateButton extends React.Component<ButtonProps, {}> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@@ -20,10 +18,10 @@ export class StateButton extends React.Component<ButtonProperties, ButtonState>
|
||||
|
||||
render() {
|
||||
var computedClassName = "";
|
||||
computedClassName += this.state.active? 'bg-white text-background-steel': 'bg-transparent text-white border-white';
|
||||
computedClassName += this.props.active? 'bg-white text-background-steel': 'bg-transparent text-white border-white';
|
||||
|
||||
return (
|
||||
<FontAwesomeIcon icon={this.props.icon as IconProp} className={computedClassName + " rounded w-5 h-5 p-2 border-2"} onClick={() => this.setState({active: !this.state.active})}>
|
||||
<FontAwesomeIcon icon={this.props.icon as IconProp} className={computedClassName + " rounded w-5 h-5 p-2 border-2"} onClick={this.props.onClick as MouseEventHandler}>
|
||||
</FontAwesomeIcon>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user