Sfoglia il codice sorgente

WIP: Blended modeling demo

Joeri Exelmans 2 anni fa
parent
commit
2117f029b7
3 ha cambiato i file con 128 aggiunte e 142 eliminazioni
  1. 93 107
      src/frontend/demo_bm.tsx
  2. 6 35
      src/frontend/demo_corr.tsx
  3. 29 0
      src/frontend/versioned_model.tsx

+ 93 - 107
src/frontend/demo_bm.tsx

@@ -1,10 +1,10 @@
 import * as React from "react";
-import {Grid, Text, Title, Group, Stack, Button, Space, Textarea, Tabs, HoverCard, ActionIcon} from "@mantine/core";
+import {SimpleGrid, Text, Title, Group, Stack, Button, Space, Textarea, Tabs, HoverCard, ActionIcon, Center} from "@mantine/core";
 
 import {PrimitiveRegistry} from "../onion/primitive_delta";
 import {mockUuid} from "../onion/test_helpers";
 
-import {newVersionedModel} from "./versioned_model";
+import {newVersionedModel, VersionedModelState} from "./versioned_model";
 import {newCorrespondence} from "./correspondence";
 
 export function getDemoBM() {
@@ -14,117 +14,103 @@ export function getDemoBM() {
   const commonStuff = {generateUUID, primitiveRegistry};
 
   const as = newVersionedModel({readonly: false, ...commonStuff});
-
   const cs1 = newVersionedModel({readonly: false, ...commonStuff});
   const cs2 = newVersionedModel({readonly: false, ...commonStuff});
-
   const corr1 = newCorrespondence({cs: cs1, as, ...commonStuff});
   const corr2 = newCorrespondence({cs: cs2, as, ...commonStuff});
 
   // returns functional react component
   return function() {
-
-    // const asState = as.useState();
-
-    // const cs1State = cs1.useState();
-    // const cs2State = cs2.useState();
-
-    // const corr1State = corr1.useState({csState: cs1State, asState});
-    // const corr2State = corr2.useState({csState: cs2State, asState});
-
-    // const asComponents = asState.getReactComponents({
-    //   onUserEdit: (...args) => {
-    //     corr1State.callbacks.render(...args);
-    //     corr2State.callbacks.render(...args);
-    //   },
-    //   onUndoClicked: asState.callbacks.undo,
-    //   onRedoClicked: asState.callbacks.redo,
-    //   onVersionClicked: asState.callbacks.gotoVersion,
-    // });
-
-    // const cs1Components = cs1State.getReactComponents({
-    //   onUserEdit: corr1State.callbacks.parse,
-    //   onUndoClicked: cs1State.callbacks.undo,
-    //   onRedoClicked: cs1State.callbacks.redo,
-    //   onVersionClicked: cs1State.callbacks.gotoVersion,
-    // });
-    // const cs2Components = cs2State.getReactComponents({
-    //   onUserEdit: corr2State.callbacks.parse,
-    //   onUndoClicked: cs2State.callbacks.undo,
-    //   onRedoClicked: cs2State.callbacks.redo,
-    //   onVersionClicked: cs2State.callbacks.gotoVersion,
-    // });
-
-    // const corr1Components = corr1State.getReactComponents({
-    //   onUndoClicked: corr1State.callbacks.gotoVersion,
-    //   onRedoClicked: corr1State.callbacks.gotoVersion,
-    //   onVersionClicked: corr1State.callbacks.gotoVersion,
-    // });
-    // const corr2Components = corr2State.getReactComponents({
-    //   onUndoClicked: corr2State.callbacks.gotoVersion,
-    //   onRedoClicked: corr2State.callbacks.gotoVersion,
-    //   onVersionClicked: corr2State.callbacks.gotoVersion,
-    // });
-
-    // const csTabs = ["editor", "state", "history", "dependencyL1", "dependencyL0"];
-    // const asTabs = ["state", "history", "dependencyL1", "dependencyL0"];
-
-    // const makeTabs = (components, defaultTab, tabs) => {
-    //   return <Tabs defaultValue={defaultTab} keepMounted={false}>
-    //     <Tabs.List>
-    //       {tabs.map(tab => ({
-    //         editor: <Tabs.Tab key={tab} value={tab}>Editor</Tabs.Tab>,
-    //         state:  <Tabs.Tab key={tab} value={tab}>State</Tabs.Tab>,
-    //         history: <Tabs.Tab key={tab} value={tab}>History</Tabs.Tab>,
-    //         dependencyL1: <Tabs.Tab key={tab} value={tab}>Deltas (L1)</Tabs.Tab>,
-    //         dependencyL0: <Tabs.Tab key={tab} value={tab}>Deltas (L0)</Tabs.Tab>,
-    //       }[tab]))}
-    //     </Tabs.List>
-    //     <Tabs.Panel value="state">
-    //       {components.graphStateComponent}
-    //     </Tabs.Panel>
-    //     <Tabs.Panel value="editor">
-    //       {components.rountangleEditor}
-    //     </Tabs.Panel>
-    //     <Tabs.Panel value="dependencyL1">
-    //       {components.depGraphL1Component}
-    //     </Tabs.Panel>
-    //     <Tabs.Panel value="dependencyL0">
-    //       {components.depGraphL0Component}
-    //     </Tabs.Panel>
-    //     <Tabs.Panel value="history">
-    //       {components.historyComponent}
-    //     </Tabs.Panel>
-    //   </Tabs>;
-    // };
-
-    // return (
-    //   <Grid grow columns={12}>
-    //     <Grid.Col span={4}>
-    //       <Title order={4}>Concrete Syntax 1</Title>
-    //       <Stack>
-    //         {makeTabs(cs1Components, "state", csTabs)}
-    //         {makeTabs(cs1Components, "history", csTabs)}
-    //         {corr1Components.undoRedoButtons}
-    //       </Stack>
-    //     </Grid.Col>
-    //     <Grid.Col span={4}>
-    //       <Title order={4}>Abstract Syntax</Title>
-    //       <Stack>
-    //         {makeTabs(asComponents, "state", asTabs)}
-    //         {makeTabs(asComponents, "history", asTabs)}
-    //       </Stack>
-    //     </Grid.Col>
-    //     <Grid.Col span={4}>
-    //       <Title order={4}>Concrete Syntax 2</Title>
-    //       <Stack>
-    //         {makeTabs(cs2Components, "state", csTabs)}
-    //         {makeTabs(cs2Components, "history", csTabs)}
-    //       </Stack>
-    //         {corr2Components.undoRedoButtons}
-    //     </Grid.Col>
-    //   </Grid>
-    // );
-    return <></>;
+    const [asState, setAsState] = React.useState<VersionedModelState>(as.initialState);
+    const [cs1State, setCs1State] = React.useState<VersionedModelState>(cs1.initialState);
+    const [cs2State, setCs2State] = React.useState<VersionedModelState>(cs2.initialState);
+    const [corr1State, setCorr1State] = React.useState<VersionedModelState>(corr1.initialState);
+    const [corr2State, setCorr2State] = React.useState<VersionedModelState>(corr2.initialState);
+
+    const asReducer = as.getReducer(setAsState);
+    const cs1Reducer = cs1.getReducer(setCs1State);
+    const cs2Reducer = cs2.getReducer(setCs2State);
+    const corr1Reducer = corr1.getReducer(setCorr1State, cs1Reducer, asReducer);
+    const corr2Reducer = corr2.getReducer(setCorr2State, cs2Reducer, asReducer);
+
+    const asComponents = as.getReactComponents(asState, {
+      onUserEdit: (deltas, description) => {
+        corr1Reducer.render(deltas, description);
+        corr2Reducer.render(deltas, description);
+      },
+      onUndoClicked: asReducer.undo,
+      onRedoClicked: asReducer.redo,
+      onVersionClicked: asReducer.gotoVersion,
+    });
+
+    const cs1Components = cs1.getReactComponents(cs1State, {
+      onUserEdit: corr1Reducer.parse,
+      onUndoClicked: cs1Reducer.undo,
+      onRedoClicked: cs1Reducer.redo,
+      onVersionClicked: cs1Reducer.gotoVersion,
+    });
+    const cs2Components = cs2.getReactComponents(cs2State, {
+      onUserEdit: corr2Reducer.parse,
+      onUndoClicked: cs2Reducer.undo,
+      onRedoClicked: cs2Reducer.redo,
+      onVersionClicked: cs2Reducer.gotoVersion,
+    });
+
+    const corr1Components = corr1.getReactComponents(corr1State, {
+      onUndoClicked: corr1Reducer.gotoVersion,
+      onRedoClicked: corr1Reducer.gotoVersion,
+      onVersionClicked: corr1Reducer.gotoVersion,
+    });
+    const corr2Components = corr2.getReactComponents(corr2State, {
+      onUndoClicked: corr2Reducer.gotoVersion,
+      onRedoClicked: corr2Reducer.gotoVersion,
+      onVersionClicked: corr2Reducer.gotoVersion,
+    });
+
+    const csTabs = ["editor", "state", "history", "dependencyL1", "dependencyL0"];
+    const corrTabs = ["state", "history", "dependencyL1", "dependencyL0"];
+    const asTabs = ["state", "history", "dependencyL1", "dependencyL0"];
+
+    return (<>
+      <SimpleGrid cols={5}>
+        <div>
+          <Title order={4}>Concrete Syntax 1</Title>
+          <Stack>
+            {cs1Components.makeTabs("editor", csTabs)}
+            {cs1Components.makeTabs("history", csTabs)}
+          </Stack>
+        </div>
+        <div>
+          <Title order={4}>Correspondence 1</Title>
+          <Stack>
+            {corr1Components.makeTabs("state", corrTabs)}
+            {corr1Components.makeTabs("history", corrTabs)}
+          </Stack>
+          <Center>{corr1Components.undoRedoButtons}</Center>
+        </div>
+        <div>
+          <Title order={4}>Abstract Syntax</Title>
+          <Stack>
+            {asComponents.makeTabs("state", asTabs)}
+            {asComponents.makeTabs("history", asTabs)}
+          </Stack>
+        </div>
+        <div>
+          <Title order={4}>Correspondence 2</Title>
+          <Stack>
+            {corr2Components.makeTabs("state", corrTabs)}
+            {corr2Components.makeTabs("history", corrTabs)}
+          </Stack>
+          <Center>{corr2Components.undoRedoButtons}</Center>
+        </div>
+        <div>
+          <Title order={4}>Concrete Syntax 2</Title>
+          <Stack>
+            {cs2Components.makeTabs("editor", csTabs)}
+            {cs2Components.makeTabs("history", csTabs)}
+          </Stack>
+        </div>
+      </SimpleGrid>
+    </>);
   }
 }

+ 6 - 35
src/frontend/demo_corr.tsx

@@ -49,56 +49,27 @@ export function getDemoCorr() {
     const corrTabs = ["state", "history", "dependencyL1", "dependencyL0"];
     const asTabs = ["state", "history", "dependencyL1", "dependencyL0"];
 
-    const makeTabs = (components, defaultTab, tabs) => {
-      return <Tabs defaultValue={defaultTab} keepMounted={false}>
-        <Tabs.List>
-          {tabs.map(tab => ({
-            editor: <Tabs.Tab key={tab} value={tab}>Editor</Tabs.Tab>,
-            state:  <Tabs.Tab key={tab} value={tab}>State</Tabs.Tab>,
-            history: <Tabs.Tab key={tab} value={tab}>History</Tabs.Tab>,
-            dependencyL1: <Tabs.Tab key={tab} value={tab}>Deltas (L1)</Tabs.Tab>,
-            dependencyL0: <Tabs.Tab key={tab} value={tab}>Deltas (L0)</Tabs.Tab>,
-          }[tab]))}
-        </Tabs.List>
-        <Tabs.Panel value="state">
-          {components.graphStateComponent}
-        </Tabs.Panel>
-        <Tabs.Panel value="editor">
-          {components.rountangleEditor}
-        </Tabs.Panel>
-        <Tabs.Panel value="dependencyL1">
-          {components.depGraphL1Component}
-        </Tabs.Panel>
-        <Tabs.Panel value="dependencyL0">
-          {components.depGraphL0Component}
-        </Tabs.Panel>
-        <Tabs.Panel value="history">
-          {components.historyComponent}
-        </Tabs.Panel>
-      </Tabs>;
-    }
-
     return (<>
       <SimpleGrid cols={3}>
         <div>
           <Title order={4}>Concrete Syntax</Title>
           <Stack>
-            {makeTabs(csComponents, "editor", csTabs)}
-            {makeTabs(csComponents, "history", csTabs)}
+            {csComponents.makeTabs("editor", csTabs)}
+            {csComponents.makeTabs("history", csTabs)}
           </Stack>
         </div>
         <div>
           <Title order={4}>Correspondence</Title>
           <Stack>
-            {makeTabs(corrComponents, "state", corrTabs)}
-            {makeTabs(corrComponents, "history", corrTabs)}
+            {corrComponents.makeTabs("state", corrTabs)}
+            {corrComponents.makeTabs("history", corrTabs)}
           </Stack>
         </div>
         <div>
           <Title order={4}>Abstract Syntax</Title>
           <Stack>
-            {makeTabs(asComponents, "state", asTabs)}
-            {makeTabs(asComponents, "history", asTabs)}
+            {asComponents.makeTabs("state", asTabs)}
+            {asComponents.makeTabs("history", asTabs)}
           </Stack>
         </div>
       </SimpleGrid>

+ 29 - 0
src/frontend/versioned_model.tsx

@@ -306,6 +306,34 @@ export function newVersionedModel({generateUUID, primitiveRegistry, readonly}) {
         <div>{stackedRedoButtons}</div>
       </Mantine.SimpleGrid>
     );
+    const makeTabs = (defaultTab: string, tabs: string[]) => {
+      return <Mantine.Tabs defaultValue={defaultTab} keepMounted={false}>
+        <Mantine.Tabs.List>
+          {tabs.map(tab => ({
+            editor: <Mantine.Tabs.Tab key={tab} value={tab}>Editor</Mantine.Tabs.Tab>,
+            state:  <Mantine.Tabs.Tab key={tab} value={tab}>State</Mantine.Tabs.Tab>,
+            history: <Mantine.Tabs.Tab key={tab} value={tab}>History</Mantine.Tabs.Tab>,
+            dependencyL1: <Mantine.Tabs.Tab key={tab} value={tab}>Deltas (L1)</Mantine.Tabs.Tab>,
+            dependencyL0: <Mantine.Tabs.Tab key={tab} value={tab}>Deltas (L0)</Mantine.Tabs.Tab>,
+          }[tab]))}
+        </Mantine.Tabs.List>
+        <Mantine.Tabs.Panel value="state">
+          {graphStateComponent}
+        </Mantine.Tabs.Panel>
+        <Mantine.Tabs.Panel value="editor">
+          {rountangleEditor}
+        </Mantine.Tabs.Panel>
+        <Mantine.Tabs.Panel value="dependencyL1">
+          {depGraphL1Component}
+        </Mantine.Tabs.Panel>
+        <Mantine.Tabs.Panel value="dependencyL0">
+          {depGraphL0Component}
+        </Mantine.Tabs.Panel>
+        <Mantine.Tabs.Panel value="history">
+          {historyComponent}
+        </Mantine.Tabs.Panel>
+      </Mantine.Tabs>;
+    }
 
     return {
       graphStateComponent,
@@ -317,6 +345,7 @@ export function newVersionedModel({generateUUID, primitiveRegistry, readonly}) {
       redoButton,
       undoRedoButtons,
       stackedUndoRedoButtons,
+      makeTabs,
     };
   }