Skip to content

Commit cd2564e

Browse files
committed
started 'NFA to DFA' feature
1 parent 63d365f commit cd2564e

File tree

10 files changed

+213
-124
lines changed

10 files changed

+213
-124
lines changed

src/components/Editor.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ import { MaxNumberOfStates } from "../consts/MaxNumberOfStates";
1919
import { AutomataData } from "./types/AutomataData";
2020
import { Tools } from "./Tools";
2121
import { ToolsProps } from "./props/ToolsProps";
22+
import { NfaToDfa } from "../features/NfaToDfa";
23+
import { NfaToDfaProps } from "../features/props/NfaToDfaProps";
24+
import {
25+
DFA_TO_MINIMIZED_DFA,
26+
NFA_TO_DFA,
27+
TEST_A_STRING,
28+
} from "./types/OperatableTools";
2229

2330
export const DataContext = createContext<AutomataData>({} as AutomataData);
2431

@@ -103,6 +110,13 @@ export const Editor = () => {
103110
const [actionState, setActionState] = useState("Normal");
104111
const [size, setSize] = useState<PlaygroundSize>({ width: 0, height: 0 });
105112

113+
const [toolOperatable, setToolOperatable] = useState<
114+
| typeof NFA_TO_DFA
115+
| typeof DFA_TO_MINIMIZED_DFA
116+
| typeof TEST_A_STRING
117+
| null
118+
>(null);
119+
106120
const handleAddRow = (row: RowModel) => {
107121
if (states.length >= MaxNumberOfStates) {
108122
alert(`Maximum ${MaxNumberOfStates} states allowed`);
@@ -550,6 +564,15 @@ export const Editor = () => {
550564

551565
const toolsProps: ToolsProps = {
552566
rows,
567+
states,
568+
transitions,
569+
setToolOperatable,
570+
};
571+
572+
const nfaToDfaProps: NfaToDfaProps = {
573+
rows,
574+
states,
575+
transitions,
553576
};
554577

555578
return (
@@ -613,6 +636,9 @@ export const Editor = () => {
613636
</Grid>
614637
</Grid>
615638
</Box>
639+
{toolOperatable && toolOperatable === NFA_TO_DFA && (
640+
<NfaToDfa {...nfaToDfaProps} />
641+
)}
616642
</>
617643
</DataContext.Provider>
618644
);

src/components/Tools.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import InboxIcon from "@mui/icons-material/MoveToInbox";
2323
import MailIcon from "@mui/icons-material/Mail";
2424
import { ToolsProps } from "./props/ToolsProps";
2525
import { IsDFA } from "../utils/IsDFA";
26+
import { NFA_TO_DFA } from "./types/OperatableTools";
2627

2728
export const Tools = (props: ToolsProps) => {
2829
console.log("re rendering Tools: props");
@@ -141,9 +142,15 @@ export const Tools = (props: ToolsProps) => {
141142
IsDFA(props.rows);
142143
}}
143144
>
144-
<Button variant="text" component="label">
145-
Is DFA
146-
</Button>
145+
Is DFA
146+
</MenuItem>
147+
<MenuItem
148+
onClick={() => {
149+
handleCloseToolsMenu();
150+
props.setToolOperatable(NFA_TO_DFA);
151+
}}
152+
>
153+
NFA To DFA
147154
</MenuItem>
148155
</Menu>
149156
</Box>

src/components/props/ToolsProps.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
1-
import { RowModel } from "../../models";
1+
import { DraggableStateModel, RowModel, TransitionModel } from "../../models";
2+
import {
3+
NFA_TO_DFA,
4+
DFA_TO_MINIMIZED_DFA,
5+
TEST_A_STRING,
6+
} from "../types/OperatableTools";
27

38
export type ToolsProps = {
49
rows: RowModel[];
10+
states: DraggableStateModel[];
11+
transitions: TransitionModel[];
12+
setToolOperatable: React.Dispatch<
13+
React.SetStateAction<
14+
| typeof NFA_TO_DFA
15+
| typeof DFA_TO_MINIMIZED_DFA
16+
| typeof TEST_A_STRING
17+
| null
18+
>
19+
>;
520
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const NFA_TO_DFA = "NFA_TO_DFA";
2+
const DFA_TO_MINIMIZED_DFA = "DFA_TO_MINIMIZED_DFA";
3+
const TEST_A_STRING = "TEST_A_STRING";
4+
5+
export { NFA_TO_DFA, DFA_TO_MINIMIZED_DFA, TEST_A_STRING };

src/consts/AnimationTimeOptions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const AnimationTimeOptions = [0.5, 1, 2, 3, 4, 5];

src/features/NfaToDfa.tsx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import {
2+
Box,
3+
Grid,
4+
Button,
5+
ButtonGroup,
6+
FormControl,
7+
InputLabel,
8+
MenuItem,
9+
Select,
10+
SelectChangeEvent,
11+
} from "@mui/material";
12+
import { useState } from "react";
13+
import { Tools } from "../components/Tools";
14+
import { AnimationTimeOptions } from "../consts/AnimationTimeOptions";
15+
import { RowModel } from "../models";
16+
import { AnimationController } from "./components/tools/AnimationController";
17+
import { AnimationControllerProps } from "./components/tools/props/AnimationControllerProps";
18+
import Playground from "./Playground";
19+
import { NfaToDfaProps } from "./props/NfaToDfaProps";
20+
import TransitionTable from "./TransitionTable";
21+
22+
export const NfaToDfa = (props: NfaToDfaProps) => {
23+
const [duration, setDuration] = useState(AnimationTimeOptions[0]);
24+
25+
const handleTimeChange = (event: SelectChangeEvent) => {
26+
setDuration(Number(event.target.value));
27+
};
28+
29+
const animationControllerProps: AnimationControllerProps = {
30+
duration: duration,
31+
handleTimeChange: handleTimeChange,
32+
};
33+
34+
return (
35+
<Box sx={{ flexGrow: 1, m: 1, mt: 5 }}>
36+
{/* Grid to incorporate Transition table and Playground */}
37+
<Grid
38+
container
39+
columnSpacing={{
40+
xs: 1,
41+
sm: 2,
42+
md: 3,
43+
}}
44+
>
45+
{/* Transition table grid */}
46+
<Grid item xs={12} md={4}>
47+
{/* Grid for Add a Row button and Tools */}
48+
<Grid container alignItems={"center"}>
49+
<Grid item xs={12}>
50+
<AnimationController {...animationControllerProps} />
51+
</Grid>
52+
</Grid>
53+
{/* <TransitionTable {...transitionTableProps} /> */}
54+
</Grid>
55+
{/* Playground grid */}
56+
<Grid item xs={12} md={8}>
57+
{/* <Playground {...playgroundProps} /> */}
58+
</Grid>
59+
</Grid>
60+
</Box>
61+
);
62+
};

src/features/TransitionTable.tsx

Lines changed: 46 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,136 +1,62 @@
1-
import { Box, Button, Grid, IconButton, Menu, Tooltip } from "@mui/material";
1+
import { Box } from "@mui/material";
22
import { DataGrid } from "@mui/x-data-grid";
33
import { darken, lighten } from "@mui/material/styles";
44
import { TransitionTableProps } from "./props/TransitionTableProps";
5-
import { RowModel } from "../models";
65
import { useState } from "react";
76
import { MaxNumberOfStates } from "../consts/MaxNumberOfStates";
8-
import MoreIcon from "@mui/icons-material/MoreVert";
9-
import { Download } from "./Download";
10-
import { Upload } from "./Upload";
117

128
const getBackgroundColor = (color: string, mode: string) =>
139
mode === "dark" ? darken(color, 0) : lighten(color, 0);
1410

1511
const TransitionTable = (props: TransitionTableProps) => {
1612
console.log("re rendering TransitionTable: props", props);
1713

18-
const [anchorElUser, setAnchorElUser] = useState<null | HTMLElement>(null);
19-
20-
const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => {
21-
setAnchorElUser(event.currentTarget);
22-
};
23-
24-
const handleCloseToolsMenu = () => {
25-
setAnchorElUser(null);
26-
};
27-
2814
return (
29-
<>
30-
{/* <Grid container alignItems={"center"}>
31-
<Grid item xs={11}>
32-
<Button
33-
size="small"
34-
onClick={() =>
35-
props.handleAddRow(
36-
new RowModel(
37-
props.rowId,
38-
`q${props.rowId}`,
39-
"",
40-
"",
41-
"",
42-
false,
43-
false
44-
)
45-
)
46-
}
47-
>
48-
Add a row
49-
</Button>
50-
</Grid>
51-
52-
<Grid item xs={1}>
53-
<Box>
54-
<Tooltip title="Tools">
55-
<IconButton
56-
size="large"
57-
aria-label="tools"
58-
aria-controls="menu-appbar-tools"
59-
aria-haspopup="true"
60-
onClick={handleOpenUserMenu}
61-
color="inherit"
62-
>
63-
<MoreIcon />
64-
</IconButton>
65-
</Tooltip>
66-
<Menu
67-
id="menu-appbar-tools"
68-
anchorEl={anchorElUser}
69-
anchorOrigin={{
70-
vertical: "bottom",
71-
horizontal: "left",
72-
}}
73-
keepMounted
74-
transformOrigin={{
75-
vertical: "top",
76-
horizontal: "left",
77-
}}
78-
open={Boolean(anchorElUser)}
79-
onClose={handleCloseToolsMenu}
80-
>
81-
<Download handleCloseToolsMenu={handleCloseToolsMenu} />
82-
<Upload handleCloseToolsMenu={handleCloseToolsMenu} />
83-
</Menu>
84-
</Box>
85-
</Grid>
86-
</Grid> */}
87-
88-
<Box
89-
sx={{
90-
"& .super-app-theme--Both": {
91-
bgcolor: (theme) =>
92-
`${getBackgroundColor(
93-
theme.palette.info.light,
94-
theme.palette.mode
95-
)} !important`,
96-
},
97-
98-
"& .super-app-theme--Initial": {
99-
bgcolor: (theme) =>
100-
`${getBackgroundColor(
101-
theme.palette.warning.light,
102-
theme.palette.mode
103-
)} !important`,
104-
},
105-
106-
"& .super-app-theme--Final": {
107-
bgcolor: (theme) =>
108-
`${getBackgroundColor(
109-
theme.palette.success.light,
110-
theme.palette.mode
111-
)} !important`,
112-
},
113-
}}
114-
>
115-
<DataGrid
116-
rows={props.rows}
117-
columns={props.columns}
118-
autoHeight
119-
hideFooter
120-
experimentalFeatures={{ newEditingApi: true }}
121-
pageSize={MaxNumberOfStates}
122-
getRowClassName={(params) =>
123-
`super-app-theme--${
124-
params?.row?.isInitial && params?.row?.isFinal
125-
? "Both"
126-
: params?.row?.isInitial
127-
? "Initial"
128-
: params?.row?.isFinal && "Final"
129-
}`
130-
}
131-
></DataGrid>
132-
</Box>
133-
</>
15+
<Box
16+
sx={{
17+
"& .super-app-theme--Both": {
18+
bgcolor: (theme) =>
19+
`${getBackgroundColor(
20+
theme.palette.info.light,
21+
theme.palette.mode
22+
)} !important`,
23+
},
24+
25+
"& .super-app-theme--Initial": {
26+
bgcolor: (theme) =>
27+
`${getBackgroundColor(
28+
theme.palette.warning.light,
29+
theme.palette.mode
30+
)} !important`,
31+
},
32+
33+
"& .super-app-theme--Final": {
34+
bgcolor: (theme) =>
35+
`${getBackgroundColor(
36+
theme.palette.success.light,
37+
theme.palette.mode
38+
)} !important`,
39+
},
40+
}}
41+
>
42+
<DataGrid
43+
rows={props.rows}
44+
columns={props.columns}
45+
autoHeight
46+
hideFooter
47+
experimentalFeatures={{ newEditingApi: true }}
48+
pageSize={MaxNumberOfStates}
49+
getRowClassName={(params) =>
50+
`super-app-theme--${
51+
params?.row?.isInitial && params?.row?.isFinal
52+
? "Both"
53+
: params?.row?.isInitial
54+
? "Initial"
55+
: params?.row?.isFinal && "Final"
56+
}`
57+
}
58+
></DataGrid>
59+
</Box>
13460
);
13561
};
13662
export default TransitionTable;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {
2+
ButtonGroup,
3+
FormControl,
4+
InputLabel,
5+
Select,
6+
MenuItem,
7+
Button,
8+
SelectChangeEvent,
9+
} from "@mui/material";
10+
import { AnimationTimeOptions } from "../../../consts/AnimationTimeOptions";
11+
import { AnimationControllerProps } from "./props/AnimationControllerProps";
12+
13+
export const AnimationController = (props: AnimationControllerProps) => (
14+
<ButtonGroup disableElevation fullWidth variant="outlined" size="large">
15+
<FormControl fullWidth>
16+
<InputLabel id="time-select-label">Time</InputLabel>
17+
<Select
18+
labelId="time-select-label"
19+
id="time-select"
20+
value={props.duration.toString()}
21+
label="Time"
22+
onChange={() => props.handleTimeChange}
23+
>
24+
{AnimationTimeOptions.map((option) => (
25+
<MenuItem key={option} value={option}>
26+
{option}
27+
</MenuItem>
28+
))}
29+
</Select>
30+
</FormControl>
31+
<Button>Pause</Button>
32+
<Button>Play</Button>
33+
</ButtonGroup>
34+
);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { SelectChangeEvent } from "@mui/material";
2+
3+
export type AnimationControllerProps = {
4+
duration: number;
5+
handleTimeChange: (event: SelectChangeEvent) => void;
6+
};

0 commit comments

Comments
 (0)