Skip to content

Commit

Permalink
#732 London style phase 2 (#902)
Browse files Browse the repository at this point in the history
  • Loading branch information
thekingofcity authored Dec 29, 2024
1 parent 91450a7 commit de5eae5
Show file tree
Hide file tree
Showing 28 changed files with 912 additions and 100 deletions.
5 changes: 5 additions & 0 deletions public/images/facilities/airport_london.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions public/images/facilities/coach_station_london.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions public/images/facilities/river_craft.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/components/panels/details/specific-attrs.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Text } from '@chakra-ui/react';
import { useTranslation } from 'react-i18next';
import { MiscNodeId, StnId } from '../../../constants/constants';
import { AttrsProps, MiscNodeId, StnId } from '../../../constants/constants';
import { useRootDispatch, useRootSelector } from '../../../redux';
import { saveGraph } from '../../../redux/param/param-slice';
import { refreshEdgesThunk, refreshNodesThunk } from '../../../redux/runtime/runtime-slice';
Expand All @@ -18,7 +18,7 @@ export const NodeSpecificAttributes = () => {
const [id] = selected;

const type = window.graph.getNodeAttribute(id, 'type');
const AttrsComponent = type in nodes && nodes[type].attrsComponent;
const AttrsComponent = type in nodes && (nodes[type].attrsComponent as React.FC<AttrsProps<any>>);
const attrs = (window.graph.getNodeAttribute(id, type) ?? {}) as any;

const handleAttrsUpdate = (selectedFirst: string, attrs: any) => {
Expand Down
8 changes: 7 additions & 1 deletion src/components/svg-canvas-graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ import singleColor from './svgs/lines/styles/single-color';
import miscNodes from './svgs/nodes/misc-nodes';
import { default as stations } from './svgs/stations/stations';

const connectableNodesType = [
...Object.values(StationType),
MiscNodeType.Virtual,
MiscNodeType.Master,
MiscNodeType.LondonArrow,
];

const SvgCanvas = () => {
const dispatch = useRootDispatch();
const graph = React.useRef(window.graph);
Expand Down Expand Up @@ -114,7 +121,6 @@ const SvgCanvas = () => {
if (mode.startsWith('line')) {
if (!keepLastPath) dispatch(setMode('free'));

const connectableNodesType = [...Object.values(StationType), MiscNodeType.Virtual, MiscNodeType.Master];
const couldActiveBeConnected =
graph.current.hasNode(active) &&
connectableNodesType.includes(graph.current.getNodeAttribute(active, 'type'));
Expand Down
8 changes: 8 additions & 0 deletions src/components/svgs/lines/lines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ import lrtSingleColor from './styles/lrt-single-color';
import londonTubeInternalInt from './styles/london-tube-internal-int';
import londonTube10MinWalk from './styles/london-tube-10-min-walk';
import londonTubeTerminal from './styles/london-tube-terminal';
import londonRail from './styles/london-rail';
import londonSandwich from './styles/london-sandwich';
import londonLutonAirportDART from './styles/london-DART';
import londonIFSCloudCableCar from './styles/london-ifs-could-cable-car';
import guangdongIntercityRailway from './styles/guangdong-intercity-railway';

export const linePaths = {
Expand Down Expand Up @@ -57,5 +61,9 @@ export const lineStyles = {
[LineStyleType.LondonTubeTerminal]: londonTubeTerminal,
[LineStyleType.LondonTubeInternalInt]: londonTubeInternalInt,
[LineStyleType.LondonTube10MinWalk]: londonTube10MinWalk,
[LineStyleType.LondonRail]: londonRail,
[LineStyleType.LondonSandwich]: londonSandwich,
[LineStyleType.LondonLutonAirportDART]: londonLutonAirportDART,
[LineStyleType.LondonIFSCloudCableCar]: londonIFSCloudCableCar,
[LineStyleType.GuangdongIntercityRailway]: guangdongIntercityRailway,
};
8 changes: 5 additions & 3 deletions src/components/svgs/lines/styles/dual-color.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,17 @@ const DualColorSwitch = () => {
};

const dualColorAttrsComponent = (props: AttrsProps<DualColorAttributes>) => {
const { t } = useTranslation();

const fields: RmgFieldsField[] = [
{
type: 'custom',
label: 'panel.details.lines.dualColor.swap',
label: t('panel.details.lines.dualColor.swap'),
component: <DualColorSwitch />,
},
{
type: 'custom',
label: 'panel.details.lines.dualColor.colorA',
label: t('panel.details.lines.dualColor.colorA'),
component: (
<ColorField
type={LineStyleType.DualColor}
Expand All @@ -107,7 +109,7 @@ const dualColorAttrsComponent = (props: AttrsProps<DualColorAttributes>) => {
},
{
type: 'custom',
label: 'panel.details.lines.dualColor.colorB',
label: t('panel.details.lines.dualColor.colorB'),
component: (
<ColorField
type={LineStyleType.DualColor}
Expand Down
78 changes: 78 additions & 0 deletions src/components/svgs/lines/styles/london-DART.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { RmgFields, RmgFieldsField } from '@railmapgen/rmg-components';
import { MonoColour } from '@railmapgen/rmg-palette-resources';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { AttrsProps, CityCode } from '../../../../constants/constants';
import {
LinePathAttributes,
LinePathType,
LineStyle,
LineStyleComponentProps,
LineStyleType,
} from '../../../../constants/lines';
import { AttributesWithColor, ColorField } from '../../../panels/details/color-field';

const LondonLutonAirportDART = (props: LineStyleComponentProps<LondonLutonAirportDARTAttributes>) => {
const { id, path, styleAttrs, handlePointerDown } = props;
const { color = defaultLondonLutonAirportDARTAttributes.color } =
styleAttrs ?? defaultLondonLutonAirportDARTAttributes;

const onPointerDown = React.useCallback(
(e: React.PointerEvent<SVGElement>) => handlePointerDown(id, e),
[id, handlePointerDown]
);

return (
<g id={id} onPointerDown={onPointerDown} cursor="pointer">
<path d={path} fill="none" stroke={color[2]} strokeWidth="5" strokeLinecap="round" />
<path
d={path}
fill="none"
stroke={color[3]}
strokeWidth="3"
strokeLinecap="round"
strokeDasharray="0.001 6"
/>
</g>
);
};

/**
* LondonLutonAirportDART specific props.
*/
export interface LondonLutonAirportDARTAttributes extends LinePathAttributes, AttributesWithColor {}

const defaultLondonLutonAirportDARTAttributes: LondonLutonAirportDARTAttributes = {
color: [CityCode.London, 'rail', '#d6ae00', MonoColour.white],
};

const londonLutonAirportDARTAttrsComponent = (props: AttrsProps<LondonLutonAirportDARTAttributes>) => {
const { t } = useTranslation();

const fields: RmgFieldsField[] = [
{
type: 'custom',
label: t('color'),
component: (
<ColorField
type={LineStyleType.LondonLutonAirportDART}
defaultTheme={defaultLondonLutonAirportDARTAttributes.color}
/>
),
},
];

return <RmgFields fields={fields} />;
};

const londonLutonAirportDART: LineStyle<LondonLutonAirportDARTAttributes> = {
component: LondonLutonAirportDART,
defaultAttrs: defaultLondonLutonAirportDARTAttributes,
attrsComponent: londonLutonAirportDARTAttrsComponent,
metadata: {
displayName: 'panel.details.lines.londonLutonAirportDART.displayName',
supportLinePathType: [LinePathType.Diagonal, LinePathType.Perpendicular, LinePathType.RotatePerpendicular],
},
};

export default londonLutonAirportDART;
72 changes: 72 additions & 0 deletions src/components/svgs/lines/styles/london-ifs-could-cable-car.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { RmgFields, RmgFieldsField } from '@railmapgen/rmg-components';
import { MonoColour } from '@railmapgen/rmg-palette-resources';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { AttrsProps, CityCode } from '../../../../constants/constants';
import {
LinePathAttributes,
LinePathType,
LineStyle,
LineStyleComponentProps,
LineStyleType,
} from '../../../../constants/lines';
import { AttributesWithColor, ColorField } from '../../../panels/details/color-field';

const LondonIFSCloudCableCar = (props: LineStyleComponentProps<LondonIFSCloudCableCarAttributes>) => {
const { id, path, styleAttrs, handlePointerDown } = props;
const { color = defaultLondonIFSCloudCableCarAttributes.color } =
styleAttrs ?? defaultLondonIFSCloudCableCarAttributes;

const onPointerDown = React.useCallback(
(e: React.PointerEvent<SVGElement>) => handlePointerDown(id, e),
[id, handlePointerDown]
);

return (
<g id={id} onPointerDown={onPointerDown} cursor="pointer">
<path d={path} fill="none" stroke={color[2]} strokeWidth="5" />
<path d={path} fill="none" stroke="white" strokeWidth="3" />
<path d={path} fill="none" stroke={color[2]} strokeWidth="1" />
</g>
);
};

/**
* LondonIFSCloudCableCar specific props.
*/
export interface LondonIFSCloudCableCarAttributes extends LinePathAttributes, AttributesWithColor {}

const defaultLondonIFSCloudCableCarAttributes: LondonIFSCloudCableCarAttributes = {
color: [CityCode.London, 'dangleway', '#dc241f', MonoColour.white],
};

const LondonIFSCloudCableCarAttrsComponent = (props: AttrsProps<LondonIFSCloudCableCarAttributes>) => {
const { t } = useTranslation();

const fields: RmgFieldsField[] = [
{
type: 'custom',
label: t('color'),
component: (
<ColorField
type={LineStyleType.LondonIFSCloudCableCar}
defaultTheme={defaultLondonIFSCloudCableCarAttributes.color}
/>
),
},
];

return <RmgFields fields={fields} />;
};

const londonIFSCloudCableCar: LineStyle<LondonIFSCloudCableCarAttributes> = {
component: LondonIFSCloudCableCar,
defaultAttrs: defaultLondonIFSCloudCableCarAttributes,
attrsComponent: LondonIFSCloudCableCarAttrsComponent,
metadata: {
displayName: 'panel.details.lines.londonIFSCloudCableCar.displayName',
supportLinePathType: [LinePathType.Diagonal, LinePathType.Perpendicular, LinePathType.RotatePerpendicular],
},
};

export default londonIFSCloudCableCar;
110 changes: 110 additions & 0 deletions src/components/svgs/lines/styles/london-rail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { RmgFields, RmgFieldsField } from '@railmapgen/rmg-components';
import { MonoColour } from '@railmapgen/rmg-palette-resources';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { AttrsProps, CityCode, Theme } from '../../../../constants/constants';
import {
LinePathAttributes,
LinePathType,
LineStyle,
LineStyleComponentProps,
LineStyleType,
} from '../../../../constants/lines';
import { ColorField } from '../../../panels/details/color-field';

const LondonRail = (props: LineStyleComponentProps<LondonRailAttributes>) => {
const { id, path, styleAttrs, handlePointerDown } = props;
const {
colorBackground = defaultLondonRailAttributes.colorBackground,
colorForeground = defaultLondonRailAttributes.colorForeground,
limitedService = defaultLondonRailAttributes.limitedService,
} = styleAttrs ?? defaultLondonRailAttributes;

const onPointerDown = React.useCallback(
(e: React.PointerEvent<SVGElement>) => handlePointerDown(id, e),
[id, handlePointerDown]
);

return !limitedService ? (
<g id={id} onPointerDown={onPointerDown} cursor="pointer">
<path d={path} fill="none" stroke={colorBackground[2]} strokeWidth="5" strokeLinecap="round" />
<path d={path} fill="none" stroke={colorForeground[2]} strokeWidth="2" strokeDasharray="7 3" />
</g>
) : (
<g id={id} onPointerDown={onPointerDown} cursor="pointer">
<path d={path} fill="none" stroke={colorBackground[2]} strokeWidth="5" strokeLinecap="round" />
<path d={path} fill="none" stroke={colorForeground[2]} strokeWidth="4.25" strokeLinecap="round" />
<path d={path} fill="none" stroke={colorBackground[2]} strokeWidth="2" strokeDasharray="7 3" />
</g>
);
};

/**
* LondonRail specific props.
*/
export interface LondonRailAttributes extends LinePathAttributes {
colorBackground: Theme;
colorForeground: Theme;
limitedService: boolean;
}

const defaultLondonRailAttributes: LondonRailAttributes = {
colorBackground: [CityCode.London, 'thameslink', '#d28db0', MonoColour.white],
colorForeground: [CityCode.London, 'white', '#ffffff', MonoColour.black],
limitedService: false,
};

const londonRailAttrsComponent = (props: AttrsProps<LondonRailAttributes>) => {
const { id, attrs, handleAttrsUpdate } = props;
const { t } = useTranslation();

const fields: RmgFieldsField[] = [
{
type: 'switch',
label: t('panel.details.lines.londonRail.limitedService'),
oneLine: true,
isChecked: attrs.limitedService,
onChange: val => {
attrs.limitedService = val;
handleAttrsUpdate(id, attrs);
},
minW: 'full',
},
{
type: 'custom',
label: t('panel.details.lines.londonRail.colorBackground'),
component: (
<ColorField
type={LineStyleType.LondonRail}
colorKey="colorBackground"
defaultTheme={defaultLondonRailAttributes.colorBackground}
/>
),
},
{
type: 'custom',
label: t('panel.details.lines.londonRail.colorForeground'),
component: (
<ColorField
type={LineStyleType.LondonRail}
colorKey="colorForeground"
defaultTheme={defaultLondonRailAttributes.colorForeground}
/>
),
},
];

return <RmgFields fields={fields} />;
};

const londonRail: LineStyle<LondonRailAttributes> = {
component: LondonRail,
defaultAttrs: defaultLondonRailAttributes,
attrsComponent: londonRailAttrsComponent,
metadata: {
displayName: 'panel.details.lines.londonRail.displayName',
supportLinePathType: [LinePathType.Diagonal, LinePathType.Perpendicular, LinePathType.RotatePerpendicular],
},
};

export default londonRail;
Loading

0 comments on commit de5eae5

Please sign in to comment.