mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-19 05:46:27 +01:00
Floor editor updates
This commit is contained in:
parent
04e6d3eeea
commit
fed35dd1f0
@ -83,6 +83,9 @@ $nitro-doorbell-height: 200px;
|
|||||||
|
|
||||||
$nitro-guide-tool-width: 250px;
|
$nitro-guide-tool-width: 250px;
|
||||||
|
|
||||||
|
$nitro-floor-editor-width: 760px;
|
||||||
|
$nitro-floor-editor-height: 500px;
|
||||||
|
|
||||||
.nitro-app {
|
.nitro-app {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
25
src/views/floorplan-editor/FloorplanEditorContext.tsx
Normal file
25
src/views/floorplan-editor/FloorplanEditorContext.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { createContext, Dispatch, FC, ProviderProps, SetStateAction, useContext } from 'react';
|
||||||
|
import { IFloorplanSettings } from './common/IFloorplanSettings';
|
||||||
|
import { IVisualizationSettings } from './common/IVisualizationSettings';
|
||||||
|
|
||||||
|
interface IFloorplanEditorContext
|
||||||
|
{
|
||||||
|
originalFloorplanSettings: IFloorplanSettings;
|
||||||
|
setOriginalFloorplanSettings: Dispatch<SetStateAction<IFloorplanSettings>>;
|
||||||
|
visualizationSettings: IVisualizationSettings;
|
||||||
|
setVisualizationSettings: Dispatch<SetStateAction<IVisualizationSettings>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FloorplanEditorContext = createContext<IFloorplanEditorContext>({
|
||||||
|
originalFloorplanSettings: null,
|
||||||
|
setOriginalFloorplanSettings: null,
|
||||||
|
visualizationSettings: null,
|
||||||
|
setVisualizationSettings: null
|
||||||
|
});
|
||||||
|
|
||||||
|
export const FloorplanEditorContextProvider: FC<ProviderProps<IFloorplanEditorContext>> = props =>
|
||||||
|
{
|
||||||
|
return <FloorplanEditorContext.Provider value={ props.value }>{ props.children }</FloorplanEditorContext.Provider>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useFloorplanEditorContext = () => useContext(FloorplanEditorContext);
|
@ -1,20 +1,6 @@
|
|||||||
.nitro-floorplan-editor {
|
.nitro-floorplan-editor {
|
||||||
width: 760px;
|
width: $nitro-floor-editor-width;
|
||||||
height: 575px;
|
height: $nitro-floor-editor-height;
|
||||||
|
|
||||||
.editor-area {
|
|
||||||
width: 100%;
|
|
||||||
height: 300px;
|
|
||||||
min-height: 300px;
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow-button {
|
|
||||||
|
|
||||||
@include media-breakpoint-up(md) {
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.floorplan-import-export {
|
.floorplan-import-export {
|
||||||
|
@ -1,29 +1,37 @@
|
|||||||
import { FloorHeightMapEvent, NitroPoint, RoomEngineEvent, RoomVisualizationSettingsEvent, UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer';
|
import { FloorHeightMapEvent, NitroPoint, RoomEngineEvent, RoomVisualizationSettingsEvent, UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
import { LocalizeText, SendMessageComposer } from '../../api';
|
import { LocalizeText, SendMessageComposer } from '../../api';
|
||||||
import { Column, Flex, Grid, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common';
|
import { Button, ButtonGroup, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common';
|
||||||
import { FloorplanEditorEvent } from '../../events';
|
import { FloorplanEditorEvent } from '../../events';
|
||||||
import { UseMessageEventHook, UseMountEffect, UseRoomEngineEvent, UseUiEvent } from '../../hooks';
|
import { UseMessageEventHook, UseRoomEngineEvent, UseUiEvent } from '../../hooks';
|
||||||
import { FloorplanEditor } from './common/FloorplanEditor';
|
import { FloorplanEditor } from './common/FloorplanEditor';
|
||||||
|
import { IFloorplanSettings } from './common/IFloorplanSettings';
|
||||||
|
import { IVisualizationSettings } from './common/IVisualizationSettings';
|
||||||
import { convertNumbersForSaving, convertSettingToNumber } from './common/Utils';
|
import { convertNumbersForSaving, convertSettingToNumber } from './common/Utils';
|
||||||
import { FloorplanEditorContextProvider } from './context/FloorplanEditorContext';
|
import { FloorplanEditorContextProvider } from './FloorplanEditorContext';
|
||||||
import { IFloorplanSettings, initialFloorplanSettings, IVisualizationSettings } from './context/FloorplanEditorContext.types';
|
|
||||||
import { FloorplanCanvasView } from './views/FloorplanCanvasView';
|
import { FloorplanCanvasView } from './views/FloorplanCanvasView';
|
||||||
import { FloorplanImportExportView } from './views/FloorplanImportExportView';
|
import { FloorplanImportExportView } from './views/FloorplanImportExportView';
|
||||||
import { FloorplanOptionsView } from './views/FloorplanOptionsView';
|
import { FloorplanOptionsView } from './views/FloorplanOptionsView';
|
||||||
|
|
||||||
export const FloorplanEditorView: FC<{}> = props =>
|
export const FloorplanEditorView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [isVisible, setIsVisible] = useState(false);
|
const [ isVisible, setIsVisible ] = useState(false);
|
||||||
const [ importExportVisible, setImportExportVisible ] = useState(false);
|
const [ importExportVisible, setImportExportVisible ] = useState(false);
|
||||||
const [originalFloorplanSettings, setOriginalFloorplanSettings] = useState<IFloorplanSettings>(initialFloorplanSettings);
|
const [ originalFloorplanSettings, setOriginalFloorplanSettings ] = useState<IFloorplanSettings>({
|
||||||
const [visualizationSettings, setVisualizationSettings] = useState<IVisualizationSettings>(
|
tilemap: '',
|
||||||
{
|
reservedTiles: [],
|
||||||
entryPointDir: 2,
|
entryPoint: [0, 0],
|
||||||
wallHeight: -1,
|
entryPointDir: 2,
|
||||||
thicknessWall: 1,
|
wallHeight: -1,
|
||||||
thicknessFloor: 1
|
thicknessWall: 1,
|
||||||
});
|
thicknessFloor: 1
|
||||||
|
});
|
||||||
|
const [ visualizationSettings, setVisualizationSettings ] = useState<IVisualizationSettings>({
|
||||||
|
entryPointDir: 2,
|
||||||
|
wallHeight: -1,
|
||||||
|
thicknessWall: 1,
|
||||||
|
thicknessFloor: 1
|
||||||
|
});
|
||||||
|
|
||||||
const onFloorplanEditorEvent = useCallback((event: FloorplanEditorEvent) =>
|
const onFloorplanEditorEvent = useCallback((event: FloorplanEditorEvent) =>
|
||||||
{
|
{
|
||||||
@ -36,20 +44,15 @@ export const FloorplanEditorView: FC<{}> = props =>
|
|||||||
setIsVisible(true);
|
setIsVisible(true);
|
||||||
break;
|
break;
|
||||||
case FloorplanEditorEvent.TOGGLE_FLOORPLAN_EDITOR:
|
case FloorplanEditorEvent.TOGGLE_FLOORPLAN_EDITOR:
|
||||||
setIsVisible(!isVisible);
|
setIsVisible(prevValue => !prevValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}, [isVisible]);
|
}, []);
|
||||||
|
|
||||||
UseUiEvent(FloorplanEditorEvent.HIDE_FLOORPLAN_EDITOR, onFloorplanEditorEvent);
|
UseUiEvent(FloorplanEditorEvent.HIDE_FLOORPLAN_EDITOR, onFloorplanEditorEvent);
|
||||||
UseUiEvent(FloorplanEditorEvent.SHOW_FLOORPLAN_EDITOR, onFloorplanEditorEvent);
|
UseUiEvent(FloorplanEditorEvent.SHOW_FLOORPLAN_EDITOR, onFloorplanEditorEvent);
|
||||||
UseUiEvent(FloorplanEditorEvent.TOGGLE_FLOORPLAN_EDITOR, onFloorplanEditorEvent);
|
UseUiEvent(FloorplanEditorEvent.TOGGLE_FLOORPLAN_EDITOR, onFloorplanEditorEvent);
|
||||||
|
|
||||||
UseMountEffect(() =>
|
|
||||||
{
|
|
||||||
FloorplanEditor.instance.initialize();
|
|
||||||
});
|
|
||||||
|
|
||||||
const onRoomEngineEvent = useCallback((event: RoomEngineEvent) =>
|
const onRoomEngineEvent = useCallback((event: RoomEngineEvent) =>
|
||||||
{
|
{
|
||||||
setIsVisible(false);
|
setIsVisible(false);
|
||||||
@ -61,18 +64,25 @@ export const FloorplanEditorView: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
if(!parser) return;
|
setOriginalFloorplanSettings(prevValue =>
|
||||||
|
{
|
||||||
|
const newValue = { ...prevValue };
|
||||||
|
|
||||||
const settings = Object.assign({}, originalFloorplanSettings);
|
newValue.tilemap = parser.model;
|
||||||
settings.tilemap = parser.model;
|
newValue.wallHeight = (parser.wallHeight + 1);
|
||||||
settings.wallHeight = parser.wallHeight + 1;
|
|
||||||
setOriginalFloorplanSettings(settings);
|
|
||||||
|
|
||||||
const vSettings = Object.assign({}, visualizationSettings);
|
return newValue;
|
||||||
vSettings.wallHeight = parser.wallHeight + 1;
|
});
|
||||||
setVisualizationSettings(vSettings);
|
|
||||||
|
|
||||||
}, [originalFloorplanSettings, visualizationSettings]);
|
setVisualizationSettings(prevValue =>
|
||||||
|
{
|
||||||
|
const newValue = { ...prevValue };
|
||||||
|
|
||||||
|
newValue.wallHeight = (parser.wallHeight + 1);
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
UseMessageEventHook(FloorHeightMapEvent, onFloorHeightMapEvent);
|
UseMessageEventHook(FloorHeightMapEvent, onFloorHeightMapEvent);
|
||||||
|
|
||||||
@ -80,23 +90,30 @@ export const FloorplanEditorView: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
if(!parser) return;
|
setOriginalFloorplanSettings(prevValue =>
|
||||||
|
{
|
||||||
|
const newValue = { ...prevValue };
|
||||||
|
|
||||||
const settings = Object.assign({}, originalFloorplanSettings);
|
newValue.thicknessFloor = convertSettingToNumber(parser.thicknessFloor);
|
||||||
settings.thicknessFloor = convertSettingToNumber(parser.thicknessFloor);
|
newValue.thicknessWall = convertSettingToNumber(parser.thicknessWall);
|
||||||
settings.thicknessWall = convertSettingToNumber(parser.thicknessWall);
|
|
||||||
|
|
||||||
setOriginalFloorplanSettings(settings);
|
return newValue;
|
||||||
|
});
|
||||||
|
|
||||||
const vSettings = Object.assign({}, visualizationSettings);
|
setVisualizationSettings(prevValue =>
|
||||||
vSettings.thicknessFloor = convertSettingToNumber(parser.thicknessFloor);
|
{
|
||||||
vSettings.thicknessWall = convertSettingToNumber(parser.thicknessWall);
|
const newValue = { ...prevValue };
|
||||||
setVisualizationSettings(vSettings);
|
|
||||||
}, [originalFloorplanSettings, visualizationSettings]);
|
newValue.thicknessFloor = convertSettingToNumber(parser.thicknessFloor);
|
||||||
|
newValue.thicknessWall = convertSettingToNumber(parser.thicknessWall);
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
UseMessageEventHook(RoomVisualizationSettingsEvent, onRoomVisualizationSettingsEvent);
|
UseMessageEventHook(RoomVisualizationSettingsEvent, onRoomVisualizationSettingsEvent);
|
||||||
|
|
||||||
const saveFloorChanges = useCallback(() =>
|
const saveFloorChanges = () =>
|
||||||
{
|
{
|
||||||
SendMessageComposer(new UpdateFloorPropertiesMessageComposer(
|
SendMessageComposer(new UpdateFloorPropertiesMessageComposer(
|
||||||
FloorplanEditor.instance.getCurrentTilemapString(),
|
FloorplanEditor.instance.getCurrentTilemapString(),
|
||||||
@ -105,47 +122,44 @@ export const FloorplanEditorView: FC<{}> = props =>
|
|||||||
visualizationSettings.entryPointDir,
|
visualizationSettings.entryPointDir,
|
||||||
convertNumbersForSaving(visualizationSettings.thicknessWall),
|
convertNumbersForSaving(visualizationSettings.thicknessWall),
|
||||||
convertNumbersForSaving(visualizationSettings.thicknessFloor),
|
convertNumbersForSaving(visualizationSettings.thicknessFloor),
|
||||||
visualizationSettings.wallHeight - 1
|
(visualizationSettings.wallHeight - 1)
|
||||||
));
|
));
|
||||||
}, [visualizationSettings.entryPointDir, visualizationSettings.thicknessFloor, visualizationSettings.thicknessWall, visualizationSettings.wallHeight]);
|
}
|
||||||
|
|
||||||
const revertChanges = useCallback(() =>
|
const revertChanges = () =>
|
||||||
{
|
{
|
||||||
setVisualizationSettings({ wallHeight: originalFloorplanSettings.wallHeight, thicknessWall: originalFloorplanSettings.thicknessWall, thicknessFloor: originalFloorplanSettings.thicknessFloor, entryPointDir: originalFloorplanSettings.entryPointDir });
|
setVisualizationSettings({ wallHeight: originalFloorplanSettings.wallHeight, thicknessWall: originalFloorplanSettings.thicknessWall, thicknessFloor: originalFloorplanSettings.thicknessFloor, entryPointDir: originalFloorplanSettings.entryPointDir });
|
||||||
|
|
||||||
FloorplanEditor.instance.doorLocation = new NitroPoint(originalFloorplanSettings.entryPoint[0], originalFloorplanSettings.entryPoint[1]);
|
FloorplanEditor.instance.doorLocation = new NitroPoint(originalFloorplanSettings.entryPoint[0], originalFloorplanSettings.entryPoint[1]);
|
||||||
FloorplanEditor.instance.setTilemap(originalFloorplanSettings.tilemap, originalFloorplanSettings.reservedTiles);
|
FloorplanEditor.instance.setTilemap(originalFloorplanSettings.tilemap, originalFloorplanSettings.reservedTiles);
|
||||||
FloorplanEditor.instance.renderTiles();
|
FloorplanEditor.instance.renderTiles();
|
||||||
}, [originalFloorplanSettings.entryPoint, originalFloorplanSettings.entryPointDir, originalFloorplanSettings.reservedTiles, originalFloorplanSettings.thicknessFloor, originalFloorplanSettings.thicknessWall, originalFloorplanSettings.tilemap, originalFloorplanSettings.wallHeight])
|
}
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
FloorplanEditor.instance.initialize();
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<FloorplanEditorContextProvider value={{ originalFloorplanSettings: originalFloorplanSettings, setOriginalFloorplanSettings: setOriginalFloorplanSettings, visualizationSettings: visualizationSettings, setVisualizationSettings: setVisualizationSettings }}>
|
||||||
<FloorplanEditorContextProvider value={{ originalFloorplanSettings: originalFloorplanSettings, setOriginalFloorplanSettings: setOriginalFloorplanSettings, visualizationSettings: visualizationSettings, setVisualizationSettings: setVisualizationSettings }}>
|
{ isVisible &&
|
||||||
{isVisible &&
|
<NitroCardView uniqueKey="floorpan-editor" className="nitro-floorplan-editor" theme="primary-slim">
|
||||||
<NitroCardView uniqueKey="floorpan-editor" className="nitro-floorplan-editor" theme="primary-slim">
|
<NitroCardHeaderView headerText={ LocalizeText('floor.plan.editor.title') } onCloseClick={ () => setIsVisible(false) } />
|
||||||
<NitroCardHeaderView headerText={LocalizeText('floor.plan.editor.title')} onCloseClick={() => setIsVisible(false)} />
|
<NitroCardContentView overflow="hidden">
|
||||||
<NitroCardContentView>
|
<FloorplanOptionsView />
|
||||||
<Grid>
|
<FloorplanCanvasView overflow="hidden" />
|
||||||
<Column size={12}>
|
<Flex justifyContent="between">
|
||||||
<FloorplanOptionsView />
|
<Button onClick={ revertChanges }>{ LocalizeText('floor.plan.editor.reload') }</Button>
|
||||||
<FloorplanCanvasView />
|
<ButtonGroup>
|
||||||
<Flex className="justify-content-between">
|
<Button disabled={ true }>{ LocalizeText('floor.plan.editor.preview') }</Button>
|
||||||
<div className="btn-group">
|
<Button onClick={ event => setImportExportVisible(true) }>{ LocalizeText('floor.plan.editor.import.export') }</Button>
|
||||||
<button className="btn btn-primary" onClick={revertChanges}>{LocalizeText('floor.plan.editor.reload')}</button>
|
<Button onClick={ saveFloorChanges }>{ LocalizeText('floor.plan.editor.save') }</Button>
|
||||||
</div>
|
</ButtonGroup>
|
||||||
<div className="btn-group">
|
</Flex>
|
||||||
<button className="btn btn-primary" disabled={true}>{LocalizeText('floor.plan.editor.preview')}</button>
|
</NitroCardContentView>
|
||||||
<button className="btn btn-primary" onClick={ () => setImportExportVisible(true) }>{LocalizeText('floor.plan.editor.import.export')}</button>
|
</NitroCardView> }
|
||||||
<button className="btn btn-primary" onClick={saveFloorChanges}>{LocalizeText('floor.plan.editor.save')}</button>
|
{ importExportVisible &&
|
||||||
</div>
|
<FloorplanImportExportView onCloseClick={ () => setImportExportVisible(false) } /> }
|
||||||
</Flex>
|
</FloorplanEditorContextProvider>
|
||||||
</Column>
|
|
||||||
</Grid>
|
|
||||||
</NitroCardContentView>
|
|
||||||
</NitroCardView>
|
|
||||||
}
|
|
||||||
{importExportVisible && <FloorplanImportExportView onCloseClick={ () => setImportExportVisible(false)}/>}
|
|
||||||
</FloorplanEditorContextProvider>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
1
src/views/floorplan-editor/common/ConvertMapToString.ts
Normal file
1
src/views/floorplan-editor/common/ConvertMapToString.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const ConvertTileMapToString = (map: string) => map.replace(/\r\n|\r|\n/g, '\n').toLowerCase();
|
8
src/views/floorplan-editor/common/IFloorplanSettings.ts
Normal file
8
src/views/floorplan-editor/common/IFloorplanSettings.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { IVisualizationSettings } from './IVisualizationSettings';
|
||||||
|
|
||||||
|
export interface IFloorplanSettings extends IVisualizationSettings
|
||||||
|
{
|
||||||
|
tilemap: string;
|
||||||
|
reservedTiles: boolean[][];
|
||||||
|
entryPoint: [ number, number ];
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
export interface IVisualizationSettings
|
||||||
|
{
|
||||||
|
entryPointDir: number;
|
||||||
|
wallHeight: number;
|
||||||
|
thicknessWall: number;
|
||||||
|
thicknessFloor: number;
|
||||||
|
}
|
@ -1,16 +0,0 @@
|
|||||||
import { createContext, FC, useContext } from 'react';
|
|
||||||
import { FloorplanEditorContextProps, IFloorplanEditorContext } from './FloorplanEditorContext.types';
|
|
||||||
|
|
||||||
const FloorplanEditorContext = createContext<IFloorplanEditorContext>({
|
|
||||||
originalFloorplanSettings: null,
|
|
||||||
setOriginalFloorplanSettings: null,
|
|
||||||
visualizationSettings: null,
|
|
||||||
setVisualizationSettings: null
|
|
||||||
});
|
|
||||||
|
|
||||||
export const FloorplanEditorContextProvider: FC<FloorplanEditorContextProps> = props =>
|
|
||||||
{
|
|
||||||
return <FloorplanEditorContext.Provider value={ props.value }>{ props.children }</FloorplanEditorContext.Provider>
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useFloorplanEditorContext = () => useContext(FloorplanEditorContext);
|
|
@ -1,37 +0,0 @@
|
|||||||
import { ProviderProps } from 'react';
|
|
||||||
|
|
||||||
export interface IFloorplanEditorContext
|
|
||||||
{
|
|
||||||
originalFloorplanSettings: IFloorplanSettings;
|
|
||||||
setOriginalFloorplanSettings: React.Dispatch<React.SetStateAction<IFloorplanSettings>>;
|
|
||||||
visualizationSettings: IVisualizationSettings;
|
|
||||||
setVisualizationSettings: React.Dispatch<React.SetStateAction<IVisualizationSettings>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IFloorplanSettings extends IVisualizationSettings {
|
|
||||||
tilemap: string;
|
|
||||||
reservedTiles: boolean[][];
|
|
||||||
entryPoint: [number, number];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IVisualizationSettings {
|
|
||||||
entryPointDir: number;
|
|
||||||
wallHeight: number;
|
|
||||||
thicknessWall: number;
|
|
||||||
thicknessFloor: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const initialFloorplanSettings: IFloorplanSettings = {
|
|
||||||
tilemap: '',
|
|
||||||
reservedTiles: [],
|
|
||||||
entryPoint: [0, 0],
|
|
||||||
entryPointDir: 2,
|
|
||||||
wallHeight: -1,
|
|
||||||
thicknessWall: 1,
|
|
||||||
thicknessFloor: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FloorplanEditorContextProps extends ProviderProps<IFloorplanEditorContext>
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
@ -1,51 +1,49 @@
|
|||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { GetOccupiedTilesMessageComposer, GetRoomEntryTileMessageComposer, NitroPoint, RoomEntryTileMessageEvent, RoomOccupiedTilesMessageEvent } from '@nitrots/nitro-renderer';
|
import { GetOccupiedTilesMessageComposer, GetRoomEntryTileMessageComposer, NitroPoint, RoomEntryTileMessageEvent, RoomOccupiedTilesMessageEvent } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { SendMessageComposer } from '../../../api';
|
import { SendMessageComposer } from '../../../api';
|
||||||
import { Flex } from '../../../common';
|
import { Base, Button, Column, ColumnProps, Flex, Grid } from '../../../common';
|
||||||
import { UseMessageEventHook, UseMountEffect } from '../../../hooks';
|
import { UseMessageEventHook } from '../../../hooks';
|
||||||
import { FloorplanEditor } from '../common/FloorplanEditor';
|
import { FloorplanEditor } from '../common/FloorplanEditor';
|
||||||
import { useFloorplanEditorContext } from '../context/FloorplanEditorContext';
|
import { IFloorplanSettings } from '../common/IFloorplanSettings';
|
||||||
|
import { useFloorplanEditorContext } from '../FloorplanEditorContext';
|
||||||
|
|
||||||
export const FloorplanCanvasView: FC<{}> = props =>
|
interface FloorplanCanvasViewProps extends ColumnProps
|
||||||
{
|
{
|
||||||
const { originalFloorplanSettings = null, setOriginalFloorplanSettings = null, visualizationSettings = null, setVisualizationSettings = null } = useFloorplanEditorContext();
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FloorplanCanvasView: FC<FloorplanCanvasViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { gap = 1, children = null, ...rest } = props;
|
||||||
const [ occupiedTilesReceived , setOccupiedTilesReceived ] = useState(false);
|
const [ occupiedTilesReceived , setOccupiedTilesReceived ] = useState(false);
|
||||||
const [ entryTileReceived, setEntryTileReceived ] = useState(false);
|
const [ entryTileReceived, setEntryTileReceived ] = useState(false);
|
||||||
|
const { originalFloorplanSettings = null, setOriginalFloorplanSettings = null, setVisualizationSettings = null } = useFloorplanEditorContext();
|
||||||
const elementRef = useRef<HTMLDivElement>(null);
|
const elementRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
return ( () =>
|
|
||||||
{
|
|
||||||
FloorplanEditor.instance.clear();
|
|
||||||
setVisualizationSettings( prev => {return { wallHeight: originalFloorplanSettings.wallHeight, thicknessWall: originalFloorplanSettings.thicknessWall, thicknessFloor: originalFloorplanSettings.thicknessFloor, entryPointDir: prev.entryPointDir } });
|
|
||||||
});
|
|
||||||
}, [originalFloorplanSettings.thicknessFloor, originalFloorplanSettings.thicknessWall, originalFloorplanSettings.wallHeight, setVisualizationSettings]);
|
|
||||||
|
|
||||||
UseMountEffect(() =>
|
|
||||||
{
|
|
||||||
SendMessageComposer(new GetRoomEntryTileMessageComposer());
|
|
||||||
SendMessageComposer(new GetOccupiedTilesMessageComposer());
|
|
||||||
FloorplanEditor.instance.tilemapRenderer.interactive = true;
|
|
||||||
elementRef.current.appendChild(FloorplanEditor.instance.renderer.view);
|
|
||||||
});
|
|
||||||
|
|
||||||
const onRoomOccupiedTilesMessageEvent = useCallback((event: RoomOccupiedTilesMessageEvent) =>
|
const onRoomOccupiedTilesMessageEvent = useCallback((event: RoomOccupiedTilesMessageEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
if(!parser) return;
|
let newFloorPlanSettings: IFloorplanSettings = null;
|
||||||
|
|
||||||
const settings = Object.assign({}, originalFloorplanSettings);
|
setOriginalFloorplanSettings(prevValue =>
|
||||||
settings.reservedTiles = parser.blockedTilesMap;
|
{
|
||||||
setOriginalFloorplanSettings(settings);
|
const newValue = { ...prevValue };
|
||||||
|
|
||||||
FloorplanEditor.instance.setTilemap(originalFloorplanSettings.tilemap, parser.blockedTilesMap);
|
newValue.reservedTiles = parser.blockedTilesMap;
|
||||||
|
|
||||||
|
newFloorPlanSettings = newValue;
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
FloorplanEditor.instance.setTilemap(newFloorPlanSettings.tilemap, parser.blockedTilesMap);
|
||||||
|
|
||||||
setOccupiedTilesReceived(true);
|
setOccupiedTilesReceived(true);
|
||||||
|
|
||||||
elementRef.current.scrollTo(FloorplanEditor.instance.view.width / 3, 0);
|
elementRef.current.scrollTo((FloorplanEditor.instance.view.width / 3), 0);
|
||||||
}, [originalFloorplanSettings, setOriginalFloorplanSettings]);
|
}, [ setOriginalFloorplanSettings ]);
|
||||||
|
|
||||||
UseMessageEventHook(RoomOccupiedTilesMessageEvent, onRoomOccupiedTilesMessageEvent);
|
UseMessageEventHook(RoomOccupiedTilesMessageEvent, onRoomOccupiedTilesMessageEvent);
|
||||||
|
|
||||||
@ -53,24 +51,33 @@ export const FloorplanCanvasView: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
if(!parser) return;
|
setOriginalFloorplanSettings(prevValue =>
|
||||||
|
{
|
||||||
|
const newValue = { ...prevValue };
|
||||||
|
|
||||||
const settings = Object.assign({}, originalFloorplanSettings);
|
newValue.entryPoint = [ parser.x, parser.y ];
|
||||||
settings.entryPoint = [parser.x, parser.y];
|
newValue.entryPointDir = parser.direction;
|
||||||
settings.entryPointDir = parser.direction;
|
|
||||||
setOriginalFloorplanSettings(settings);
|
|
||||||
|
|
||||||
const vSettings = Object.assign({}, visualizationSettings);
|
return newValue;
|
||||||
vSettings.entryPointDir = parser.direction;
|
});
|
||||||
setVisualizationSettings(vSettings);
|
|
||||||
|
setVisualizationSettings(prevValue =>
|
||||||
|
{
|
||||||
|
const newValue = { ...prevValue };
|
||||||
|
|
||||||
|
newValue.entryPointDir = parser.direction;
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
|
|
||||||
FloorplanEditor.instance.doorLocation = new NitroPoint(parser.x, parser.y);
|
FloorplanEditor.instance.doorLocation = new NitroPoint(parser.x, parser.y);
|
||||||
|
|
||||||
setEntryTileReceived(true);
|
setEntryTileReceived(true);
|
||||||
}, [originalFloorplanSettings, setOriginalFloorplanSettings, setVisualizationSettings, visualizationSettings]);
|
}, [ setOriginalFloorplanSettings, setVisualizationSettings ]);
|
||||||
|
|
||||||
UseMessageEventHook(RoomEntryTileMessageEvent, onRoomEntryTileMessageEvent);
|
UseMessageEventHook(RoomEntryTileMessageEvent, onRoomEntryTileMessageEvent);
|
||||||
|
|
||||||
const onClickArrowButton = useCallback((scrollDirection: string) =>
|
const onClickArrowButton = (scrollDirection: string) =>
|
||||||
{
|
{
|
||||||
const element = elementRef.current;
|
const element = elementRef.current;
|
||||||
|
|
||||||
@ -91,29 +98,92 @@ export const FloorplanCanvasView: FC<{}> = props =>
|
|||||||
element.scrollBy({ left: 10 });
|
element.scrollBy({ left: 10 });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}, []);
|
}
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if(entryTileReceived && occupiedTilesReceived)
|
return () =>
|
||||||
FloorplanEditor.instance.renderTiles();
|
{
|
||||||
}, [entryTileReceived, occupiedTilesReceived])
|
FloorplanEditor.instance.clear();
|
||||||
|
|
||||||
|
setVisualizationSettings(prevValue =>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
wallHeight: originalFloorplanSettings.wallHeight,
|
||||||
|
thicknessWall: originalFloorplanSettings.thicknessWall,
|
||||||
|
thicknessFloor: originalFloorplanSettings.thicknessFloor,
|
||||||
|
entryPointDir: prevValue.entryPointDir
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [ originalFloorplanSettings.thicknessFloor, originalFloorplanSettings.thicknessWall, originalFloorplanSettings.wallHeight, setVisualizationSettings ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!entryTileReceived || !occupiedTilesReceived) return;
|
||||||
|
|
||||||
|
FloorplanEditor.instance.renderTiles();
|
||||||
|
}, [ entryTileReceived, occupiedTilesReceived ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
SendMessageComposer(new GetRoomEntryTileMessageComposer());
|
||||||
|
SendMessageComposer(new GetOccupiedTilesMessageComposer());
|
||||||
|
|
||||||
|
FloorplanEditor.instance.tilemapRenderer.interactive = true;
|
||||||
|
|
||||||
|
if(!elementRef.current) return;
|
||||||
|
|
||||||
|
elementRef.current.appendChild(FloorplanEditor.instance.renderer.view);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Column gap={ gap } { ...rest }>
|
||||||
<Flex className="align-items-center justify-content-center">
|
<Grid overflow="hidden" gap={ 1 }>
|
||||||
<div className="arrow-button"><button className="btn btn-primary" onClick={() => onClickArrowButton('up')}><i className="fas fa-arrow-up"/></button></div>
|
<Column center size={ 1 }>
|
||||||
</Flex>
|
<Button className="d-md-none" onClick={ event => onClickArrowButton('left') }>
|
||||||
<Flex className="align-items-center justify-content-center">
|
<FontAwesomeIcon icon="arrow-left" />
|
||||||
<div className="arrow-button"><button className="btn btn-primary" onClick={() => onClickArrowButton('left')}><i className="fas fa-arrow-left"/></button></div>
|
</Button>
|
||||||
<div className="rounded-2 overflow-hidden">
|
</Column>
|
||||||
<div ref={elementRef} className="editor-area" />
|
<Column overflow="hidden" size={ 10 } gap={ 1 }>
|
||||||
</div>
|
<Flex justifyContent="center" className="d-md-none">
|
||||||
<div className="arrow-button"><button className="btn btn-primary" onClick={() => onClickArrowButton('right')}><i className="fas fa-arrow-right"/></button></div>
|
<Button shrink onClick={ event => onClickArrowButton('up') }>
|
||||||
</Flex>
|
<FontAwesomeIcon icon="arrow-up" />
|
||||||
<Flex className="align-items-center justify-content-center">
|
</Button>
|
||||||
<div className="arrow-button"><button className="btn btn-primary" onClick={() => onClickArrowButton('down')}><i className="fas fa-arrow-down"/></button></div>
|
</Flex>
|
||||||
</Flex>
|
<Base overflow="auto" innerRef={ elementRef } />
|
||||||
</>
|
<Flex justifyContent="center" className="d-md-none">
|
||||||
|
<Button shrink onClick={ event => onClickArrowButton('down') }>
|
||||||
|
<FontAwesomeIcon icon="arrow-down" />
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</Column>
|
||||||
|
<Column center size={ 1 }>
|
||||||
|
<Button className="d-md-none" onClick={ event => onClickArrowButton('right') }>
|
||||||
|
<FontAwesomeIcon icon="arrow-right" />
|
||||||
|
</Button>
|
||||||
|
</Column>
|
||||||
|
</Grid>
|
||||||
|
{/* <Flex center className="d-md-none">
|
||||||
|
<Button onClick={ event => onClickArrowButton('up') }>
|
||||||
|
<FontAwesomeIcon icon="arrow-up" />
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
<Flex center gap={ 1 }>
|
||||||
|
<Button className="d-md-none" onClick={ event => onClickArrowButton('left') }>
|
||||||
|
<FontAwesomeIcon icon="arrow-left" />
|
||||||
|
</Button>
|
||||||
|
<Base overflow="auto" innerRef={ elementRef } />
|
||||||
|
<Button className="d-md-none" onClick={ event => onClickArrowButton('right') }>
|
||||||
|
<FontAwesomeIcon icon="arrow-right" />
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
<Flex center className="d-md-none">
|
||||||
|
<Button onClick={ event => onClickArrowButton('down') }>
|
||||||
|
<FontAwesomeIcon icon="arrow-down" />
|
||||||
|
</Button>
|
||||||
|
</Flex> */}
|
||||||
|
{ children }
|
||||||
|
</Column>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,24 @@
|
|||||||
import { UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer';
|
import { UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useState } from 'react';
|
||||||
import { LocalizeText, SendMessageComposer } from '../../../api';
|
import { LocalizeText, SendMessageComposer } from '../../../api';
|
||||||
import { Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../common';
|
import { Button, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../common';
|
||||||
import { UseMountEffect } from '../../../hooks';
|
import { UseMountEffect } from '../../../hooks';
|
||||||
|
import { ConvertTileMapToString } from '../common/ConvertMapToString';
|
||||||
import { convertNumbersForSaving } from '../common/Utils';
|
import { convertNumbersForSaving } from '../common/Utils';
|
||||||
import { useFloorplanEditorContext } from '../context/FloorplanEditorContext';
|
import { useFloorplanEditorContext } from '../FloorplanEditorContext';
|
||||||
|
|
||||||
|
interface FloorplanImportExportViewProps
|
||||||
|
{
|
||||||
|
onCloseClick(): void;
|
||||||
|
}
|
||||||
|
|
||||||
export const FloorplanImportExportView: FC<FloorplanImportExportViewProps> = props =>
|
export const FloorplanImportExportView: FC<FloorplanImportExportViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { originalFloorplanSettings = null, setOriginalFloorplanSettings = null } = useFloorplanEditorContext();
|
|
||||||
|
|
||||||
const { onCloseClick = null } = props;
|
const { onCloseClick = null } = props;
|
||||||
const [ map, setMap ] = useState<string>('');
|
const [ map, setMap ] = useState<string>('');
|
||||||
|
const { originalFloorplanSettings = null } = useFloorplanEditorContext();
|
||||||
|
|
||||||
const convertMapToString = useCallback((map: string) =>
|
const saveFloorChanges = () =>
|
||||||
{
|
|
||||||
return map.replace(/\r\n|\r|\n/g, '\n').toLowerCase();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const revertChanges= useCallback(() =>
|
|
||||||
{
|
|
||||||
setMap(convertMapToString(originalFloorplanSettings.tilemap));
|
|
||||||
}, [convertMapToString, originalFloorplanSettings.tilemap]);
|
|
||||||
|
|
||||||
const saveFloorChanges = useCallback(() =>
|
|
||||||
{
|
{
|
||||||
SendMessageComposer(new UpdateFloorPropertiesMessageComposer(
|
SendMessageComposer(new UpdateFloorPropertiesMessageComposer(
|
||||||
map.split('\n').join('\r'),
|
map.split('\n').join('\r'),
|
||||||
@ -34,35 +29,27 @@ export const FloorplanImportExportView: FC<FloorplanImportExportViewProps> = pro
|
|||||||
convertNumbersForSaving(originalFloorplanSettings.thicknessFloor),
|
convertNumbersForSaving(originalFloorplanSettings.thicknessFloor),
|
||||||
originalFloorplanSettings.wallHeight - 1
|
originalFloorplanSettings.wallHeight - 1
|
||||||
));
|
));
|
||||||
}, [map, originalFloorplanSettings.entryPoint, originalFloorplanSettings.entryPointDir, originalFloorplanSettings.thicknessFloor, originalFloorplanSettings.thicknessWall, originalFloorplanSettings.wallHeight]);
|
}
|
||||||
|
|
||||||
UseMountEffect(() =>
|
UseMountEffect(() =>
|
||||||
{
|
{
|
||||||
revertChanges();
|
setMap(ConvertTileMapToString(originalFloorplanSettings.tilemap));
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardView theme="primary-slim" className="floorplan-import-export">
|
<NitroCardView theme="primary-slim" className="floorplan-import-export">
|
||||||
<NitroCardHeaderView headerText={LocalizeText('floor.plan.editor.import.export')} onCloseClick={ onCloseClick } />
|
<NitroCardHeaderView headerText={ LocalizeText('floor.plan.editor.import.export') } onCloseClick={ onCloseClick } />
|
||||||
<NitroCardContentView>
|
<NitroCardContentView>
|
||||||
<Column size={ 12 } className="h-100">
|
<textarea className="h-100" value={ map } onChange={ event => setMap(event.target.value) } />
|
||||||
<textarea className="h-100" value={map} onChange={ event => setMap(event.target.value) }></textarea>
|
<Flex justifyContent="between">
|
||||||
<Flex className="justify-content-between">
|
<Button onClick={ event => setMap(ConvertTileMapToString(originalFloorplanSettings.tilemap))}>
|
||||||
<div className="btn-group">
|
{ LocalizeText('floor.plan.editor.revert.to.last.received.map') }
|
||||||
<button className="btn btn-primary" onClick={revertChanges}>{LocalizeText('floor.plan.editor.revert.to.last.received.map')}</button>
|
</Button>
|
||||||
</div>
|
<Button onClick={ saveFloorChanges }>
|
||||||
<div className="btn-group">
|
{ LocalizeText('floor.plan.editor.save') }
|
||||||
<button className="btn btn-primary" onClick={saveFloorChanges}>{LocalizeText('floor.plan.editor.save')}</button>
|
</Button>
|
||||||
</div>
|
</Flex>
|
||||||
</Flex>
|
|
||||||
</Column>
|
|
||||||
|
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
)
|
);
|
||||||
}
|
|
||||||
|
|
||||||
export interface FloorplanImportExportViewProps
|
|
||||||
{
|
|
||||||
onCloseClick(): void;
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import ReactSlider from 'react-slider';
|
import ReactSlider from 'react-slider';
|
||||||
import { LocalizeText } from '../../../api';
|
import { LocalizeText } from '../../../api';
|
||||||
import { Base, Column, Flex, Grid, LayoutGridItem } from '../../../common';
|
import { Column, Flex, LayoutGridItem, Text } from '../../../common';
|
||||||
import { COLORMAP, FloorAction } from '../common/Constants';
|
import { COLORMAP, FloorAction } from '../common/Constants';
|
||||||
import { FloorplanEditor } from '../common/FloorplanEditor';
|
import { FloorplanEditor } from '../common/FloorplanEditor';
|
||||||
import { useFloorplanEditorContext } from '../context/FloorplanEditorContext';
|
import { useFloorplanEditorContext } from '../FloorplanEditorContext';
|
||||||
|
|
||||||
const MIN_WALL_HEIGHT: number = 0;
|
const MIN_WALL_HEIGHT: number = 0;
|
||||||
const MAX_WALL_HEIGHT: number = 16;
|
const MAX_WALL_HEIGHT: number = 16;
|
||||||
@ -111,77 +112,75 @@ export const FloorplanOptionsView: FC<{}> = props =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid className="h-auto">
|
<Column>
|
||||||
<Column size={ 5 }>
|
<Flex gap={ 1 }>
|
||||||
<Column gap={ 2 } overflow="hidden">
|
<Column size={ 5 } gap={ 1 }>
|
||||||
<Base className="flex-shrink-0 fw-bold text-black text-truncate">{ LocalizeText('floor.plan.editor.draw.mode') }</Base>
|
<Text bold>{ LocalizeText('floor.plan.editor.draw.mode') }</Text>
|
||||||
<Grid>
|
<Flex gap={ 3 }>
|
||||||
<LayoutGridItem itemActive={ (floorAction === FloorAction.SET) } onClick={ event => selectAction(FloorAction.SET) }>
|
<Flex gap={ 1 }>
|
||||||
<i className="icon icon-set-tile" />
|
<LayoutGridItem itemActive={ (floorAction === FloorAction.SET) } onClick={ event => selectAction(FloorAction.SET) }>
|
||||||
</LayoutGridItem>
|
<i className="icon icon-set-tile" />
|
||||||
<LayoutGridItem itemActive={ (floorAction === FloorAction.UNSET) } onClick={ event => selectAction(FloorAction.UNSET) }>
|
</LayoutGridItem>
|
||||||
<i className="icon icon-unset-tile" />
|
<LayoutGridItem itemActive={ (floorAction === FloorAction.UNSET) } onClick={ event => selectAction(FloorAction.UNSET) }>
|
||||||
</LayoutGridItem>
|
<i className="icon icon-unset-tile" />
|
||||||
<LayoutGridItem itemActive={ (floorAction === FloorAction.UP) } onClick={ event => selectAction(FloorAction.UP) }>
|
</LayoutGridItem>
|
||||||
<i className="icon icon-increase-height" />
|
</Flex>
|
||||||
</LayoutGridItem>
|
<Flex gap={ 1 }>
|
||||||
<LayoutGridItem itemActive={ (floorAction === FloorAction.DOWN) } onClick={ event => selectAction(FloorAction.DOWN) }>
|
<LayoutGridItem itemActive={ (floorAction === FloorAction.UP) } onClick={ event => selectAction(FloorAction.UP) }>
|
||||||
<i className="icon icon-decrease-height" />
|
<i className="icon icon-increase-height" />
|
||||||
</LayoutGridItem>
|
</LayoutGridItem>
|
||||||
|
<LayoutGridItem itemActive={ (floorAction === FloorAction.DOWN) } onClick={ event => selectAction(FloorAction.DOWN) }>
|
||||||
|
<i className="icon icon-decrease-height" />
|
||||||
|
</LayoutGridItem>
|
||||||
|
</Flex>
|
||||||
<LayoutGridItem itemActive={ (floorAction === FloorAction.DOOR) } onClick={ event => selectAction(FloorAction.DOOR) }>
|
<LayoutGridItem itemActive={ (floorAction === FloorAction.DOOR) } onClick={ event => selectAction(FloorAction.DOOR) }>
|
||||||
<i className="icon icon-set-door" />
|
<i className="icon icon-set-door" />
|
||||||
</LayoutGridItem>
|
</LayoutGridItem>
|
||||||
</Grid>
|
|
||||||
</Column>
|
|
||||||
</Column>
|
|
||||||
<Column className="align-items-center overflow-hidden" size={ 4 }>
|
|
||||||
<Column gap={ 2 } overflow="hidden">
|
|
||||||
<Base className="flex-shrink-0 fw-bold text-black text-truncate">{ LocalizeText('floor.plan.editor.enter.direction') }</Base>
|
|
||||||
<i className={ `icon icon-door-direction-${ visualizationSettings.entryPointDir } cursor-pointer` } onClick={ changeDoorDirection } />
|
|
||||||
</Column>
|
|
||||||
</Column>
|
|
||||||
<Column className="align-items-center" size={ 3 }>
|
|
||||||
<Column gap={ 2 } overflow="hidden">
|
|
||||||
<Base className="flex-shrink-0 fw-bold text-black text-truncate">{ LocalizeText('floor.editor.wall.height') }</Base>
|
|
||||||
<Flex className="align-items-center">
|
|
||||||
<i className="fas fa-caret-left cursor-pointer me-1 text-black" onClick={ decreaseWallHeight } />
|
|
||||||
<input type="number" className="form-control form-control-sm quantity-input" value={ visualizationSettings.wallHeight } onChange={ event => onWallHeightChange(event.target.valueAsNumber)} />
|
|
||||||
<i className="fas fa-caret-right cursor-pointer ms-1 text-black" onClick={ increaseWallHeight } />
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</Column>
|
</Column>
|
||||||
</Column>
|
<Column alignItems="center" size={ 4 }>
|
||||||
<Column size={ 5 }>
|
<Text bold>{ LocalizeText('floor.plan.editor.enter.direction') }</Text>
|
||||||
<Column gap={ 2 } overflow="hidden">
|
<i className={ `icon icon-door-direction-${ visualizationSettings.entryPointDir } cursor-pointer` } onClick={ changeDoorDirection } />
|
||||||
<Base className="flex-shrink-0 fw-bold text-black text-truncate">{ LocalizeText('floor.plan.editor.tile.height') }: { floorHeight }</Base>
|
</Column>
|
||||||
|
<Column size={ 3 }>
|
||||||
|
<Text bold>{ LocalizeText('floor.editor.wall.height') }</Text>
|
||||||
|
<Flex alignItems="center" gap={ 1 }>
|
||||||
|
<FontAwesomeIcon icon="caret-left" className="cursor-pointer" onClick={ decreaseWallHeight } />
|
||||||
|
<input type="number" className="form-control form-control-sm quantity-input" value={ visualizationSettings.wallHeight } onChange={ event => onWallHeightChange(event.target.valueAsNumber)} />
|
||||||
|
<FontAwesomeIcon icon="caret-right" className="cursor-pointer" onClick={ increaseWallHeight } />
|
||||||
|
</Flex>
|
||||||
|
</Column>
|
||||||
|
</Flex>
|
||||||
|
<Flex gap={ 1 }>
|
||||||
|
<Column size={ 6 }>
|
||||||
|
<Text bold>{ LocalizeText('floor.plan.editor.tile.height') }: { floorHeight }</Text>
|
||||||
<ReactSlider
|
<ReactSlider
|
||||||
className="nitro-slider"
|
className="nitro-slider"
|
||||||
min={ MIN_FLOOR_HEIGHT }
|
min={ MIN_FLOOR_HEIGHT }
|
||||||
max={ MAX_FLOOR_HEIGHT }
|
max={ MAX_FLOOR_HEIGHT }
|
||||||
step={ 1 }
|
step={ 1 }
|
||||||
value={ floorHeight }
|
value={ floorHeight }
|
||||||
onChange={ event => onFloorHeightChange(event) }
|
onChange={ event => onFloorHeightChange(event) }
|
||||||
renderThumb={ ({ style, ...rest }, state) => <div style={ { backgroundColor: `#${COLORMAP[state.valueNow.toString(33)]}`, ...style } } { ...rest }>{ state.valueNow }</div> } />
|
renderThumb={ ({ style, ...rest }, state) => <div style={ { backgroundColor: `#${COLORMAP[state.valueNow.toString(33)]}`, ...style } } { ...rest }>{ state.valueNow }</div> } />
|
||||||
</Column>
|
</Column>
|
||||||
</Column>
|
<Column size={ 6 }>
|
||||||
<Column size={5}>
|
<Text bold>{ LocalizeText('floor.plan.editor.room.options') }</Text>
|
||||||
<Column gap={ 2 } overflow="hidden">
|
<Flex className="align-items-center">
|
||||||
<Base className="flex-shrink-0 fw-bold text-black text-truncate">{ LocalizeText('floor.plan.editor.room.options') }</Base>
|
<select className="form-control form-control-sm" value={ visualizationSettings.thicknessWall } onChange={ event => onWallThicknessChange(parseInt(event.target.value)) }>
|
||||||
<Flex className="align-items-center">
|
<option value={ 0 }>{ LocalizeText('navigator.roomsettings.wall_thickness.thinnest') }</option>
|
||||||
<select className="form-control form-control-sm" value={visualizationSettings.thicknessWall} onChange={event => onWallThicknessChange(parseInt(event.target.value))}>
|
<option value={ 1 }>{ LocalizeText('navigator.roomsettings.wall_thickness.thin') }</option>
|
||||||
<option value={0}>{ LocalizeText('navigator.roomsettings.wall_thickness.thinnest') }</option>
|
<option value={ 2 }>{ LocalizeText('navigator.roomsettings.wall_thickness.normal') }</option>
|
||||||
<option value={1}>{ LocalizeText('navigator.roomsettings.wall_thickness.thin') }</option>
|
<option value={ 3 }>{ LocalizeText('navigator.roomsettings.wall_thickness.thick') }</option>
|
||||||
<option value={2}>{ LocalizeText('navigator.roomsettings.wall_thickness.normal') }</option>
|
</select>
|
||||||
<option value={3}>{ LocalizeText('navigator.roomsettings.wall_thickness.thick') }</option>
|
<select className="form-control form-control-sm" value={ visualizationSettings.thicknessFloor } onChange={ event => onFloorThicknessChange(parseInt(event.target.value)) }>
|
||||||
</select>
|
<option value={ 0 }>{ LocalizeText('navigator.roomsettings.floor_thickness.thinnest') }</option>
|
||||||
<select className="form-control form-control-sm" value={visualizationSettings.thicknessFloor} onChange={event => onFloorThicknessChange(parseInt(event.target.value))}>
|
<option value={ 1 }>{ LocalizeText('navigator.roomsettings.floor_thickness.thin') }</option>
|
||||||
<option value={0}>{ LocalizeText('navigator.roomsettings.floor_thickness.thinnest') }</option>
|
<option value={ 2 }>{ LocalizeText('navigator.roomsettings.floor_thickness.normal') }</option>
|
||||||
<option value={1}>{ LocalizeText('navigator.roomsettings.floor_thickness.thin') }</option>
|
<option value={ 3 }>{ LocalizeText('navigator.roomsettings.floor_thickness.thick') }</option>
|
||||||
<option value={2}>{ LocalizeText('navigator.roomsettings.floor_thickness.normal') }</option>
|
</select>
|
||||||
<option value={3}>{ LocalizeText('navigator.roomsettings.floor_thickness.thick') }</option>
|
</Flex>
|
||||||
</select>
|
|
||||||
</Flex>
|
|
||||||
</Column>
|
</Column>
|
||||||
</Column>
|
</Flex>
|
||||||
</Grid>
|
</Column>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user