Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/components/svgs/lines/lines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import guangdongIntercityRailway from './styles/guangdong-intercity-railway';
import chongqingRTLoop from './styles/chongqingrt-loop';
import chongqingRTLineBadge from './styles/chongqingrt-line-badge';
import chengduRTOutsideFareGates from './styles/chengdurt-outside-fare-gates';
import generic from './styles/generic';

export const linePaths = {
[LinePathType.Diagonal]: diagonalPath,
Expand Down Expand Up @@ -76,4 +77,5 @@ export const lineStyles = {
[LineStyleType.ChongqingRTLoop]: chongqingRTLoop,
[LineStyleType.ChongqingRTLineBadge]: chongqingRTLineBadge,
[LineStyleType.ChengduRTOutsideFareGates]: chengduRTOutsideFareGates,
[LineStyleType.Generic]: generic,
};
194 changes: 194 additions & 0 deletions src/components/svgs/lines/styles/generic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
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 {
LINE_WIDTH,
LinePathAttributes,
LinePathType,
LineStyle,
LineStyleComponentProps,
LineStyleType,
} from '../../../../constants/lines';
import { ColorAttribute, ColorField } from '../../../panels/details/color-field';

const Generic = (props: LineStyleComponentProps<GenericAttributes>) => {
const { id, path, styleAttrs, handlePointerDown } = props;
const {
color = defaultGenericAttributes.color,
width = defaultGenericAttributes.width,
linecap = defaultGenericAttributes.linecap,
dasharray = defaultGenericAttributes.dasharray,
outline = defaultGenericAttributes.outline,
outlineColor = defaultGenericAttributes.outlineColor,
outlineWidth = defaultGenericAttributes.outlineWidth,
} = styleAttrs ?? defaultGenericAttributes;

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

if (!outline) {
return (
<path
id={id}
d={path}
fill="none"
stroke={color[2]}
strokeWidth={width}
strokeLinecap={linecap}
strokeDasharray={dasharray}
cursor="pointer"
onPointerDown={onPointerDown}
/>
);
}

return (
<g id={id} onPointerDown={onPointerDown} cursor="pointer">
<path
d={path}
fill="none"
stroke={outlineColor[2]}
strokeWidth={outlineWidth}
strokeLinecap={linecap}
strokeDasharray={dasharray}
/>
<path
d={path}
fill="none"
stroke={color[2]}
strokeWidth={width}
strokeLinecap={linecap}
strokeDasharray={dasharray}
/>
</g>
);
};

/**
* Generic specific props.
*/
export interface GenericAttributes extends LinePathAttributes, ColorAttribute {
width: number;
linecap: 'butt' | 'round' | 'square';
dasharray: string;
outline: boolean;
outlineColor: Theme;
outlineWidth: number;
}

const defaultGenericAttributes: GenericAttributes = {
color: [CityCode.Shanghai, 'sh1', '#E4002B', MonoColour.white],
width: LINE_WIDTH,
linecap: 'round',
dasharray: '',
outline: false,
outlineColor: [CityCode.Shanghai, 'sh1', '#000000', MonoColour.white],
outlineWidth: LINE_WIDTH + 2,
};

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

const fields: RmgFieldsField[] = [
{
type: 'custom',
label: t('color'),
component: <ColorField type={LineStyleType.Generic} defaultTheme={defaultGenericAttributes.color} />,
},
{
type: 'input',
label: t('panel.details.lines.generic.width'),
variant: 'number',
value: (attrs.width ?? defaultGenericAttributes.width).toString(),
validator: (val: string) => !Number.isNaN(val) && Number(val) > 0,
onChange: val => {
attrs.width = Number(val);
handleAttrsUpdate(id, attrs);
},
},
{
type: 'select',
label: t('panel.details.lines.generic.linecap'),
value: attrs.linecap ?? defaultGenericAttributes.linecap,
options: {
butt: t('panel.details.lines.generic.linecapButt'),
round: t('panel.details.lines.generic.linecapRound'),
square: t('panel.details.lines.generic.linecapSquare'),
},
onChange: val => {
attrs.linecap = val as 'butt' | 'round' | 'square';
handleAttrsUpdate(id, attrs);
},
},
{
type: 'input',
label: t('panel.details.lines.generic.dasharray'),
value: attrs.dasharray ?? defaultGenericAttributes.dasharray,
onChange: val => {
attrs.dasharray = val as string;
handleAttrsUpdate(id, attrs);
},
},
{
type: 'switch',
label: t('panel.details.lines.generic.outline'),
oneLine: true,
isChecked: attrs.outline ?? defaultGenericAttributes.outline,
onChange: val => {
attrs.outline = val;
handleAttrsUpdate(id, attrs);
},
minW: 'full',
},
...((attrs.outline ?? defaultGenericAttributes.outline)
? [
{
type: 'custom' as const,
label: t('panel.details.lines.generic.outlineColor'),
component: (
<ColorField
type={LineStyleType.Generic}
colorKey="outlineColor"
defaultTheme={defaultGenericAttributes.outlineColor}
/>
),
},
{
type: 'input' as const,
label: t('panel.details.lines.generic.outlineWidth'),
variant: 'number' as const,
value: (attrs.outlineWidth ?? defaultGenericAttributes.outlineWidth).toString(),
validator: (val: string) => !Number.isNaN(val) && Number(val) > 0,
onChange: (val: string) => {
attrs.outlineWidth = Number(val);
handleAttrsUpdate(id, attrs);
},
},
]
: []),
];

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

const generic: LineStyle<GenericAttributes> = {
component: Generic,
defaultAttrs: defaultGenericAttributes,
attrsComponent: genericAttrsComponent,
metadata: {
displayName: 'panel.details.lines.generic.displayName',
supportLinePathType: [
LinePathType.Diagonal,
LinePathType.Perpendicular,
LinePathType.RotatePerpendicular,
LinePathType.Simple,
],
},
};

export default generic;
3 changes: 3 additions & 0 deletions src/constants/lines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { GZMTRLoopAttributes } from '../components/svgs/lines/styles/gzmtr-loop'
import { ChongqingRTLoopAttributes } from '../components/svgs/lines/styles/chongqingrt-loop';
import { ChongqingRTLineBadgeAttributes } from '../components/svgs/lines/styles/chongqingrt-line-badge';
import { ChengduRTOutsideFareGatesAttributes } from '../components/svgs/lines/styles/chengdurt-outside-fare-gates';
import { GenericAttributes } from '../components/svgs/lines/styles/generic';

export enum LinePathType {
Diagonal = 'diagonal',
Expand Down Expand Up @@ -85,6 +86,7 @@ export enum LineStyleType {
ChongqingRTLoop = 'chongqingrt-loop',
ChongqingRTLineBadge = 'chongqingrt-line-badge',
ChengduRTOutsideFareGates = 'chengdurt-outside-fare-gates',
Generic = 'generic',
}

export interface ExternalLineStyleAttributes {
Expand Down Expand Up @@ -120,6 +122,7 @@ export interface ExternalLineStyleAttributes {
[LineStyleType.ChongqingRTLoop]?: ChongqingRTLoopAttributes;
[LineStyleType.ChongqingRTLineBadge]?: ChongqingRTLineBadgeAttributes;
[LineStyleType.ChengduRTOutsideFareGates]?: ChengduRTOutsideFareGatesAttributes;
[LineStyleType.Generic]?: GenericAttributes;
}

/* ----- Below are core types for all lines, DO NOT TOUCH. ----- */
Expand Down
Loading