Skip to content

Commit

Permalink
#673 Support GZMTR loop line
Browse files Browse the repository at this point in the history
  • Loading branch information
wongchito committed Jan 23, 2025
1 parent f096c38 commit a2bb2ab
Show file tree
Hide file tree
Showing 24 changed files with 371 additions and 67 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@railmapgen/rmg-palette-resources": "^2.2.5",
"@railmapgen/rmg-runtime": "^10.3.2",
"@railmapgen/rmg-translate": "^3.2.3",
"@railmapgen/svg-assets": "^5.0.7",
"@railmapgen/svg-assets": "^5.0.10",
"@reduxjs/toolkit": "^2.5.0",
"ag-grid-community": "^33.0.4",
"ag-grid-react": "^33.0.4",
Expand Down
3 changes: 2 additions & 1 deletion public/styles/share_gzmtr.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.rmg-name__zh {
dominant-baseline: central;
font-family: Arial, SimHei, STHeitiSC-Medium, PingFangSC-Regular, sans-serif;
font-family: Arial, SimHei, STHeitiSC-Medium, 'PingFang SC', sans-serif;
font-weight: normal;
}
.rmg-name__en {
dominant-baseline: middle;
Expand Down
5 changes: 3 additions & 2 deletions src/components/ag-grid/grid-tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default function GridTabs() {
const [isNewBranchModalOpen, setIsNewBranchModalOpen] = useState(false);

const selectedBranch = useRootSelector(state => state.app.selectedBranch);
const { style, stn_list: stationList } = useRootSelector(state => state.param);
const { style, stn_list: stationList, loop } = useRootSelector(state => state.param);
const branches = useRootSelector(state => state.helper.branches);

const handleEditLineSection = () => {
Expand All @@ -40,7 +40,7 @@ export default function GridTabs() {
<TabList>
{branches.map((branch, i) => {
if (i === 0) {
return <Tab key={i}>{t('GridTabs.main')}</Tab>;
return <Tab key={i}>{loop ? t('Loop line') : t('GridTabs.main')}</Tab>;
} else {
if (style !== RmgStyle.SHMetro || !isColineBranch(branch, stationList)) {
return <Tab key={i}>{t('GridTabs.branch') + ' ' + i}</Tab>;
Expand All @@ -56,6 +56,7 @@ export default function GridTabs() {
aria-label="New branch"
onClick={() => setIsNewBranchModalOpen(true)}
icon={<MdAdd />}
isDisabled={loop}
/>

<HStack marginLeft="auto" marginRight={1}>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ag-grid/station-ag-grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export default function StationAgGrid(props: StationAgGridProps) {
hide: ![RmgStyle.SHMetro].includes(style),
},
],
[style, theme.toString(), i18n.language]
[style, theme.toString(), i18n.language, lineNumber]
);

const gridRef = useRef<AgGridReact>(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import { RmgSidePanelFooter } from '@railmapgen/rmg-components';
import { useState } from 'react';
import { useRootDispatch, useRootSelector } from '../../../redux';
import RemoveConfirmModal from '../../modal/remove-confirm-modal';
import { setCurrentStation } from '../../../redux/param/param-slice';
import { setCurrentStation, setLoopMidpointStation } from '../../../redux/param/param-slice';
import { useTranslation } from 'react-i18next';
import { RmgStyle } from '../../../constants/constants';

export default function StationSidePanelFooter() {
const { t } = useTranslation();
const dispatch = useRootDispatch();

const selectedStation = useRootSelector(state => state.app.selectedStation);
const { selectedStation } = useRootSelector(state => state.app);
const { loop, style } = useRootSelector(state => state.param);

const [isRemoveModalOpen, setIsRemoveModalOpen] = useState(false);

Expand All @@ -20,6 +22,15 @@ export default function StationSidePanelFooter() {
<Button size="sm" variant="outline" onClick={() => dispatch(setCurrentStation(selectedStation))}>
{t('StationSidePanel.footer.current')}
</Button>
{style === RmgStyle.GZMTR && loop && (
<Button
size="sm"
variant="outline"
onClick={() => dispatch(setLoopMidpointStation(selectedStation))}
>
{t('Set as midpoint')}
</Button>
)}
<Button size="sm" variant="outline" onClick={() => setIsRemoveModalOpen(true)}>
{t('StationSidePanel.footer.remove')}
</Button>
Expand Down
41 changes: 33 additions & 8 deletions src/components/side-panel/style-side-panel/loop-section.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import { Box, Heading } from '@chakra-ui/react';
import { useRootDispatch, useRootSelector } from '../../../redux';
import { setLoop, setLoopBank, setLoopBottomFactor, setLoopLeftAndRightFactor } from '../../../redux/param/param-slice';
import { RmgFields, RmgFieldsField } from '@railmapgen/rmg-components';
import {
setLoop,
setLoopBank,
setLoopBottomFactor,
setLoopClockwise,
setLoopLeftAndRightFactor,
} from '../../../redux/param/param-slice';
import { RmgButtonGroup, RmgFields, RmgFieldsField } from '@railmapgen/rmg-components';
import { useTranslation } from 'react-i18next';
import { RmgStyle } from '../../../constants/constants';

export default function LoopSection() {
const { t } = useTranslation();
const dispatch = useRootDispatch();

const { branches } = useRootSelector(state => state.helper);
const { loop, loop_info } = useRootSelector(state => state.param);
const { bank, left_and_right_factor, bottom_factor } = loop_info;
const { loop, loop_info, style } = useRootSelector(state => state.param);
const { bank, left_and_right_factor, bottom_factor, clockwise } = loop_info;

// loop line with 2 branches has no bottom_factor and a specialized left_and_right_factor_max
const arc: 'major' | 'minor' = 'minor';
Expand Down Expand Up @@ -46,7 +53,7 @@ export default function LoopSection() {
onChange: checked => dispatch(setLoopBank(checked)),
minW: 'full',
oneLine: true,
hidden: !loop,
hidden: !loop || style !== RmgStyle.SHMetro,
},
{
type: 'slider',
Expand All @@ -55,7 +62,7 @@ export default function LoopSection() {
min: 0,
max: left_and_right_factor_max,
onChange: val => dispatch(setLoopLeftAndRightFactor(Math.floor(val))),
hidden: !loop,
hidden: !loop || style !== RmgStyle.SHMetro,
},
{
type: 'slider',
Expand All @@ -64,14 +71,32 @@ export default function LoopSection() {
min: 0,
max: Math.floor((branches[0].length - 2 - left_and_right_factor * 2) / 2),
onChange: val => dispatch(setLoopBottomFactor(Math.floor(val))),
hidden: !loop || (loop && branches.length > 2),
hidden: !loop || (loop && branches.length > 2) || style !== RmgStyle.SHMetro,
},
{
type: 'custom',
label: t('Loop direction'),
component: (
<RmgButtonGroup
selections={
[
{ label: t('Anticlockwise'), value: false },
{ label: t('Clockwise'), value: true },
] as { label: string; value: boolean }[]
}
defaultValue={clockwise ?? false}
onChange={ccw => dispatch(setLoopClockwise(ccw))}
/>
),
hidden: !loop || ![RmgStyle.GZMTR].includes(style),
oneLine: true,
},
];

return (
<Box p={1}>
<Heading as="h5" size="sm">
{t('StyleSidePanel.loop.title')}
{t('StyleSidePanel.loop.title')} {style === RmgStyle.GZMTR ? '(Beta)' : ''}
</Heading>

<RmgFields fields={fields} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ export default function StyleSidePanel() {

<DesignSection />

{style === RmgStyle.GZMTR && (
{[RmgStyle.GZMTR, RmgStyle.SHMetro].includes(style) && (
<>
<Divider />

<GZMTRNoteSection />
<LoopSection />
</>
)}

{style === RmgStyle.SHMetro && (
{style === RmgStyle.GZMTR && (
<>
<Divider />

<LoopSection />
<GZMTRNoteSection />
</>
)}
</RmgSidePanelBody>
Expand Down
2 changes: 2 additions & 0 deletions src/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ export interface RMGParam {
* Also, this factor is subject to several rules, see shmetro-loop for more info.
*/
bottom_factor: number;
midpoint_station?: string;
clockwise?: boolean;
};
version?: string; // RMG version
}
Expand Down
2 changes: 1 addition & 1 deletion src/i18n/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"zhLineName": "Chinese line name",
"enLineName": "English line name",
"lineNum": "Line code",
"direction": "Train direction",
"direction": "Train direction at this station",
"left": "Left",
"right": "Right",
"platformNum": "Platform number",
Expand Down
8 changes: 7 additions & 1 deletion src/i18n/translations/zh-Hans.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"zhLineName": "路线中文名称",
"enLineName": "路线英文名称",
"lineNum": "路线编号",
"direction": "行车方向",
"direction": "当前车站行车方向",
"left": "向左",
"right": "向右",
"platformNum": "站台编号",
Expand Down Expand Up @@ -216,6 +216,7 @@

"Airport": "机场",
"All projects": "所有项目",
"Anticlockwise": "逆时针",
"Are you sure to remove station? You cannot undo this action.": "您确定刪除此车站吗?您不能撤销此操作。",
"Blank project": "空白项目",
"Branch left end": "支线左端",
Expand All @@ -227,6 +228,8 @@
"by": "来自",
"Canvas scale": "画面缩放级别",
"Chinese name": "中文名称",
"Circle line": "环线",
"Clockwise": "顺时针",
"Close": "关闭",
"Colour": "颜色",
"Connect to main line": "连接至主线",
Expand All @@ -247,6 +250,8 @@
"Just now": "刚刚",
"Last modified": "上次编辑",
"LEFT END": "线路左端",
"Loop direction": "环线方向",
"Loop line": "环线",
"Manage": "管理",
"Manage projects": "管理项目",
"minute ago": "分钟前",
Expand All @@ -271,6 +276,7 @@
"Saved projects": "保存的项目",
"Secondary names": "第二名称",
"Select canvas": "选择画面",
"Set as midpoint": "设置为半环站",
"Span digits over rows": "跨行显示数字",
"Style": "风格",
"Station Chinese name": "车站中文名称",
Expand Down
8 changes: 7 additions & 1 deletion src/i18n/translations/zh-Hant.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"zhLineName": "路綫中文名稱",
"enLineName": "路綫英文名稱",
"lineNum": "路綫編碼",
"direction": "行車方向",
"direction": "當前車站行車方向",
"left": "向左",
"right": "向右",
"platformNum": "月台編號",
Expand Down Expand Up @@ -208,6 +208,7 @@

"Airport": "機場",
"All projects": "所有專案",
"Anticlockwise": "反時針",
"Are you sure to remove station? You cannot undo this action.": "確定移除該車站嗎?此動作無法還原。",
"Blank project": "空白專案",
"Branch left end": "支綫左端",
Expand All @@ -219,6 +220,8 @@
"by": "來自",
"Canvas scale": "畫面縮放比例",
"Chinese name": "中文名稱",
"Circle line": "環綫",
"Clockwise": "順時針",
"Close": "關閉",
"Colour": "顏色",
"Connect to main line": "連接至主綫",
Expand All @@ -239,6 +242,8 @@
"Just now": "剛才",
"Last modified": "上次修改",
"LEFT END": "路綫左端",
"Loop direction": "環綫方向",
"Loop line": "環綫",
"Manage": "管理",
"Manage projects": "管理專案",
"minute ago": "分鐘前",
Expand All @@ -263,6 +268,7 @@
"Saved projects": "儲存的專案",
"Secondary names": "第二名稱",
"Select canvas": "選擇畫面",
"Set as midpoint": "設定為半環站",
"Span digits over rows": "跨行顯示數字",
"Style": "風格",
"Station Chinese name": "車站中文名稱",
Expand Down
10 changes: 10 additions & 0 deletions src/redux/param/param-slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ const paramSlice = createSlice({
state.loop_info.bottom_factor = action.payload;
},

setLoopMidpointStation: (state, action: PayloadAction<string>) => {
state.loop_info.midpoint_station = action.payload;
},

setLoopClockwise: (state, action: PayloadAction<boolean>) => {
state.loop_info.clockwise = action.payload;
},

setCurrentStation: (state, action: PayloadAction<string>) => {
state.current_stn_idx = action.payload;
},
Expand Down Expand Up @@ -190,6 +198,8 @@ export const {
setLoopBank,
setLoopLeftAndRightFactor,
setLoopBottomFactor,
setLoopMidpointStation,
setLoopClockwise,
setCurrentStation,
setStation,
setStations,
Expand Down
1 change: 0 additions & 1 deletion src/redux/param/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ const initLineName = (language: LanguageCode): Name => {

export const initStationInfo = (id: string): StationInfo => ({
localisedName: { zh: '未命名 ' + id, en: 'Unnamed ' + id },
localisedSecondaryName: {},
num: '00',
services: [Services.local],
parents: [],
Expand Down
2 changes: 1 addition & 1 deletion src/svgs/gzmtr/current-station-name.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default memo(
if (nameEl.current && onUpdate) {
onUpdate(nameEl.current.getBBox());
}
}, [stnName.toString()]);
}, [JSON.stringify(stnName)]);

return (
<g ref={nameEl}>
Expand Down
Loading

0 comments on commit a2bb2ab

Please sign in to comment.