Skip to content

Commit

Permalink
Delete selected edge
Browse files Browse the repository at this point in the history
- Delete with CMD+Backspace
- Delete with control button click
  • Loading branch information
antonvolkoff committed Jul 5, 2020
1 parent 6900ea6 commit 8fcd4a5
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 12 deletions.
16 changes: 16 additions & 0 deletions src/canvas/edge.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Edge from "./edge";
import edge from "./edge";

describe("id", () => {
test("should create an id from an edge", () => {
const edge = { sourceId: "1", targetId: "2" };
expect(Edge.id(edge)).toEqual("1-->2");
});
});

describe("parseId", () => {
test("should return an edge from an id", () => {
const id = "1-->2";
expect(Edge.parseId(id)).toEqual({ sourceId: "1", targetId: "2" });
});
});
9 changes: 8 additions & 1 deletion src/canvas/edge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ interface Edge {
targetId: string;
}

const ArrowSymbol = "-->";

export default {
id: (edge: Edge): string => `${edge.sourceId}-->${edge.targetId}`,
id: (edge: Edge): string => `${edge.sourceId}${ArrowSymbol}${edge.targetId}`,

parseId: (edgeId: string): Edge => {
const [sourceId, targetId] = edgeId.split(ArrowSymbol);
return { sourceId, targetId };
},
};
11 changes: 7 additions & 4 deletions src/interface/control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { html } from "htm/react";
import { Store } from "redux";

import { ApplicationState } from "../store";
import { deleteAtom, evalSelectedAtom } from "../store/defaultReducer";
import { deleteAtom, evalSelectedAtom, deleteEdge } from "../store/defaultReducer";
import { selectors as canvasSelectors } from "../canvas";
import PlayIcon from "./play_icon";
import TrashIcon from "./trash_icon";
import CastIcon from "./cast_icon";
import BookIcon from "./book_icon";
import { actions } from "./interfaceReducer";

const { getSelectedAtomId } = canvasSelectors;
const { getSelectedAtomId, getSelectedEdgeId } = canvasSelectors;
const { toggleTranscript } = actions;

interface Props {
Expand All @@ -20,10 +20,12 @@ interface Props {

export default function Control({ store }: Props) {
const [selectedAtomId, setSelectedAtomId] = useState(null);
const [selectedEdgeId, setSelectedEdgeId] = useState(null);
const [connectedToRepl, setConnectedToRepl] = useState(false);

store.subscribe(() => {
setSelectedAtomId(getSelectedAtomId(store.getState()));
setSelectedEdgeId(getSelectedEdgeId(store.getState()));
setConnectedToRepl(store.getState().default.connectedToRepl);
});

Expand All @@ -36,7 +38,8 @@ export default function Control({ store }: Props) {
const onDeleteClick = (event) => {
event.preventDefault();
event.stopPropagation();
store.dispatch(deleteAtom(selectedAtomId));
if (selectedAtomId) store.dispatch(deleteAtom(selectedAtomId));
if (selectedEdgeId) store.dispatch(deleteEdge(selectedEdgeId));
}

const onTranscriptClick = (event) => {
Expand All @@ -58,7 +61,7 @@ export default function Control({ store }: Props) {
<${PlayIcon} />
</button>
<button className="control-button"
disabled=${!selectedAtomId}
disabled=${!selectedAtomId && !selectedEdgeId}
onClick=${onDeleteClick}>
<${TrashIcon} />
</button>
Expand Down
28 changes: 21 additions & 7 deletions src/keyboard/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as Mousetrap from "mousetrap";
import { ApplicationState } from "../store";
import {
deleteAtom as deleteAtomAction, addAtom, connectAtoms, childrenSelector,
evalSelectedAtom, parentSelector, deepChildrenSelector
evalSelectedAtom, parentSelector, deepChildrenSelector, deleteEdge
} from "../store/defaultReducer";
import { buildNodeGeometry } from "../canvas/node_geometry";
import { createAtom } from "../store/atom";
Expand All @@ -16,30 +16,44 @@ import { remote } from "electron";
const { dialog } = remote;
const { select, unselect, changeMode } = actions;
const { toggleTranscript } = interfaceActions;
const { getSelectedAtom, getMode } = selectors;
const { getSelectedAtom, getMode, getSelectedEdgeId } = selectors;

export default function Keyboard(store: Store<ApplicationState>) {
let state = store.getState();
let mode = getMode(store.getState());
let selectedAtom = getSelectedAtom(store.getState());
let selectedEdgeId = getSelectedEdgeId(store.getState());

store.subscribe(() => {
state = store.getState();
mode = getMode(store.getState());
selectedAtom = getSelectedAtom(store.getState());
selectedEdgeId = getSelectedEdgeId(store.getState());
});

const standardAtomOffset = 40;
const evaluateAtom = () => store.dispatch(evalSelectedAtom());
const deleteAtom = (event) => {
if (!selectedAtom) return;

event.preventDefault();

const deleteSelectedAtom = () => {
const parent = parentSelector(state.default, selectedAtom.id);
store.dispatch(deleteAtomAction(selectedAtom.id));
if (parent) store.dispatch(select(parent.id));
};

const deleteSelectedEdge = () => store.dispatch(deleteEdge(selectedEdgeId));

const deleteSelectedElement = (event) => {
if (selectedAtom) {
event.preventDefault();
deleteSelectedAtom();
}

if (selectedEdgeId) {
event.preventDefault();
deleteSelectedEdge();
}
};

const createChildAtom = (event) => {
if (!selectedAtom) return;

Expand Down Expand Up @@ -163,7 +177,7 @@ export default function Keyboard(store: Store<ApplicationState>) {
};

Mousetrap.bind("command+e", evaluateAtom);
Mousetrap.bind("command+backspace", deleteAtom);
Mousetrap.bind("command+backspace", deleteSelectedElement);
Mousetrap.bind("tab", createChildAtom);
Mousetrap.bind("command+enter", handleCmdEnter);
Mousetrap.bind("esc", handleEsc);
Expand Down
11 changes: 11 additions & 0 deletions src/store/defaultReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { buildNodeGeometry } from "../canvas/node_geometry";
import { Line } from "../canvas/geometry";
import { ApplicationState } from ".";
import { EvalResult } from "../repl";
import Edge from "../canvas/edge";

export interface DefaultState {
atoms: { [id: string]: Atom };
Expand Down Expand Up @@ -43,6 +44,10 @@ export const setAtomValue =
export const evalSelectedAtom =
() => ({ type: "eval-selected-atom" });

export const deleteEdge = (edgeId: string) => (
{ type: "delete-edge", payload: Edge.parseId(edgeId) }
);

const initialState: DefaultState = {
atoms: {},
edges: [],
Expand All @@ -66,6 +71,12 @@ const reducer = createReducer(initialState, {
return !isSource && !isTarget;
});
},
"delete-edge": (state, action) => {
const notMatchingEdge = (signature) => ({ sourceId, targetId }) => (
!(sourceId === signature.sourceId && targetId === signature.targetId)
);
state.edges = state.edges.filter(notMatchingEdge(action.payload));
},
"add-atom": (state, action) => {
state.atoms[action.payload.id] = action.payload;
},
Expand Down

0 comments on commit 8fcd4a5

Please sign in to comment.