Extended signal rendering, minor tweaks

+Added extended signal rendering option (currently showing placeholder svg)
*Side menu CSS tweaks
*Track on-hover info is now enabled by default
This commit is contained in:
izawartka 2025-06-26 17:48:47 +02:00
parent ac9e0493a1
commit 2c42291139
7 changed files with 122 additions and 33 deletions

View File

@ -5,7 +5,8 @@ import Constants from "../helpers/constants";
export default function SettingsManager(props) {
const [ layers, setLayers ] = useState([]);
const [ trackColorMode, setTrackColorMode ] = useState(Constants.trackColorModeDefault);
const [ showTrackHoverInfo, setShowTrackHoverInfo ] = useState(false);
const [ showTrackHoverInfo, setShowTrackHoverInfo ] = useState(true);
const [ extendedSignals, setExtendedSignals ] = useState(true);
const [ settingsLoaded, setSettingsLoaded ] = useState(false);
const loadLayersSettings = useCallback(() => {
@ -26,7 +27,8 @@ export default function SettingsManager(props) {
<SettingsContext.Provider value={{
layers, setLayers,
showTrackHoverInfo, setShowTrackHoverInfo,
trackColorMode, setTrackColorMode
trackColorMode, setTrackColorMode,
extendedSignals, setExtendedSignals,
}}>
{ props.children }
</SettingsContext.Provider>

View File

@ -0,0 +1,33 @@
import { ReactSVG } from 'react-svg'
import AngleHelper from '../../../helpers/angleHelper';
export default function SignalExtendedRenderer(props) {
const { object } = props;
const [x, y] = object.pos.toSVGCoords();
const rot = AngleHelper.normalizeDegAngle(object.rot.y);
const upsideDown = rot >= 180;
const upsideDownRot = upsideDown ? 90 : -90;
const anchor = upsideDown ? "start" : "end";
return (
<g className="signal" transform={`translate(${x}, ${y}) rotate(${object.rot.y})`}>
<g className="signal-icon" transform={`translate(-1.89, -9.1476)`}>
<ReactSVG
src={`${process.env.PUBLIC_URL}/assets/signal-test-new.svg`}
wrapper='svg'
beforeInjection={(svg) => {
svg.setAttribute('width', '1mm');
svg.setAttribute('height', '3.3mm');
}}
/>
</g>
<g transform={`translate(0, 4) rotate(${upsideDownRot})`}>
<text x="0" y="0" textAnchor={anchor} dominantBaseline="middle">
{object.getPrintableSignalName()}
</text>
</g>
</g>
);
}

View File

@ -1,33 +1,18 @@
import { ReactSVG } from 'react-svg'
import AngleHelper from '../../../helpers/angleHelper';
import React, { useContext } from 'react';
import SignalStandardRenderer from './SignalStandardRenderer';
import SignalExtendedRenderer from './SignalExtendedRenderer';
import SettingsContext from '../../../contexts/SettingsContext';
export default function SignalRenderer(props) {
const { object } = props;
const [x, y] = object.pos.toSVGCoords();
const rot = AngleHelper.normalizeDegAngle(object.rot.y);
const upsideDown = rot >= 180;
const upsideDownRot = upsideDown ? 90 : -90;
const anchor = upsideDown ? "end" : "start";
return (
<g className="signal" transform={`translate(${x}, ${y}) rotate(${object.rot.y})`}>
<g className="signal-icon" transform={`translate(-1.89, -1.89)`}>
<ReactSVG
src={`${process.env.PUBLIC_URL}/assets/signal.svg`}
wrapper='svg'
beforeInjection={(svg) => {
svg.setAttribute('width', '1mm');
svg.setAttribute('height', '1mm');
}}
/>
</g>
<g transform={`translate(0, -2) rotate(${upsideDownRot})`}>
<text x="0" y="0" textAnchor={anchor} dominantBaseline="middle">
{object.getPrintableSignalName()}
</text>
</g>
</g>
);
const { extendedSignals } = useContext(SettingsContext);
if (extendedSignals) {
return <MemoizedSignalExtendedRenderer object={object} />;
} else {
return <MemoizedSignalStandardRenderer object={object} />;
}
}
const MemoizedSignalStandardRenderer = React.memo(SignalStandardRenderer);
const MemoizedSignalExtendedRenderer = React.memo(SignalExtendedRenderer);

View File

@ -0,0 +1,33 @@
import { ReactSVG } from "react-svg";
import AngleHelper from "../../../helpers/angleHelper";
export default function SignalStandardRenderer(props) {
const { object } = props;
const [x, y] = object.pos.toSVGCoords();
const rot = AngleHelper.normalizeDegAngle(object.rot.y);
const upsideDown = rot >= 180;
const upsideDownRot = upsideDown ? 90 : -90;
const anchor = upsideDown ? "end" : "start";
return (
<g className="signal" transform={`translate(${x}, ${y}) rotate(${object.rot.y})`}>
<g className="signal-icon" transform={`translate(-1.89, -1.89)`}>
<ReactSVG
src={`${process.env.PUBLIC_URL}/assets/signal.svg`}
wrapper='svg'
beforeInjection={(svg) => {
svg.setAttribute('width', '1mm');
svg.setAttribute('height', '1mm');
}}
/>
</g>
<g transform={`translate(0, -2) rotate(${upsideDownRot})`}>
<text x="0" y="0" textAnchor={anchor} dominantBaseline="middle">
{object.getPrintableSignalName()}
</text>
</g>
</g>
);
}

View File

@ -0,0 +1,26 @@
import { useContext } from "react";
import SettingsContext from "../../contexts/SettingsContext";
export default function ExtendedSignalsCheckbox(props) {
const { extendedSignals, setExtendedSignals, layers } = useContext(SettingsContext);
const handleChange = (event) => {
setExtendedSignals(event.target.checked);
};
let divClass = 'extended-signals-checkbox';
if(!layers['signals']) divClass += ' hidden';
return (
<div className={divClass}>
<label>
<input
type="checkbox"
checked={extendedSignals}
onChange={handleChange}
/>
Extended signal rendering
</label>
</div>
);
}

View File

@ -1,3 +1,4 @@
import ExtendedSignalsCheckbox from "./ExtendedSignalsCheckbox";
import ShowTrackHoverInfoCheckbox from "./ShowTrackHoverInfoCheckbox";
import TrackColorMode from "./track-color-mode/TrackColorMode";
@ -5,7 +6,10 @@ export default function LayerOptionsMenu() {
return (
<div className="layer-options-menu">
<h3>Layer options</h3>
<ShowTrackHoverInfoCheckbox />
<div className="layer-options-menu-checkboxes">
<ShowTrackHoverInfoCheckbox />
<ExtendedSignalsCheckbox />
</div>
<TrackColorMode />
</div>
);

View File

@ -21,7 +21,12 @@
.layer-options-menu {
display: flex;
flex-direction: column;
gap: 1em;
gap: 0.5em;
}
.layer-options-menu-checkboxes {
display: flex;
flex-direction: column;
}
.side-menu .hidden {
@ -73,6 +78,7 @@
align-items: flex-end;
}
.extended-signals-checkbox input,
.show-track-hover-info-checkbox input {
margin-right: 0.5em;
vertical-align: middle;