diff --git a/editor/src/App.tsx b/editor/src/App.tsx index 4c1ab4d..9da2f87 100644 --- a/editor/src/App.tsx +++ b/editor/src/App.tsx @@ -13,7 +13,7 @@ function App(): ReactElement {

nandsim

- +
); diff --git a/editor/src/Canvas.tsx b/editor/src/Canvas.tsx index 1bf2269..c674b06 100644 --- a/editor/src/Canvas.tsx +++ b/editor/src/Canvas.tsx @@ -2,9 +2,9 @@ import { useEffect, type ReactElement, type RefObject } from "react"; import { type Editor } from "./editor/Editor"; import { v2 } from "./editor/V2"; -type Props = { editor: Editor; canvasRef: RefObject }; +type Props = { editor: Editor; canvasRef: RefObject, width: number, height: number }; -function Canvas({ editor, canvasRef }: Props): ReactElement { +function Canvas({ editor, canvasRef, width, height }: Props): ReactElement { useEffect(() => { if (!canvasRef.current) return; @@ -16,9 +16,9 @@ function Canvas({ editor, canvasRef }: Props): ReactElement {
{ const pos = v2(ev.nativeEvent.offsetX, ev.nativeEvent.offsetY); diff --git a/editor/src/editor/Board.ts b/editor/src/editor/Board.ts index de0c701..68e484c 100644 --- a/editor/src/editor/Board.ts +++ b/editor/src/editor/Board.ts @@ -83,7 +83,7 @@ export class Board { this.hoveredOverOutput?.[0] === comp && this.hoveredOverOutput[1] === i ) { - c.strokeStyle = `#bbbbbb`; + c.strokeStyle = `#eee`; c.lineWidth = 2; c.beginPath(); c.arc(x + w, y + (i + 1) * pinSpace, 5, 0, Math.PI * 2); @@ -135,6 +135,55 @@ export class Board { } } } + + handleMouseClick( + pos: V2, + inputPinClicked: (comp: Component, i: number) => void, + outputPinClicked: (comp: Component, i: number) => void, + componentClicked: (comp: Component) => void, + ): "handled" | "not handled" { + for (const comp of this.components) { + const { + pos: { x, y }, + def: { + size: { x: w, y: h }, + inputs, + outputs, + }, + } = comp; + + if ( + !pointInsideRect( + pos, + comp.pos.sub(v2(5, 5)), + comp.def.size.add(v2(10, 10)), + ) + ) { + continue; + } + { + const pinSpace = h / (inputs.length + 1); + for (let i = 0; i < inputs.length; ++i) { + if (v2(x, y + (i + 1) * pinSpace).distance(pos) < 5) { + inputPinClicked(comp, i); + return "handled"; + } + } + } + { + const pinSpace = h / (outputs.length + 1); + for (let i = 0; i < outputs.length; ++i) { + if (v2(x + w, y + (i + 1) * pinSpace).distance(pos) < 5) { + outputPinClicked(comp, i); + return "handled"; + } + } + } + componentClicked(comp); + return "handled"; + } + return "not handled"; + } } export class ComponentRepo { diff --git a/editor/src/editor/states/Normal.ts b/editor/src/editor/states/Normal.ts index 1087796..2d76395 100644 --- a/editor/src/editor/states/Normal.ts +++ b/editor/src/editor/states/Normal.ts @@ -23,8 +23,19 @@ export class Normal implements State { } onMouseDown(pos: V2): void { - this.cx.addSelectionRect(pos); - this.cx.transitionTo(new Selecting(this.cx)); + if ( + this.cx.board.handleMouseClick( + pos.sub(this.cx.offset), + (comp, i) => {}, + (comp, i) => {}, + (comp) => {}, + ) === "handled" + ) { + return; + } else { + this.cx.addSelectionRect(pos); + this.cx.transitionTo(new Selecting(this.cx)); + } } onMouseMove(_deltaPos: V2, pos: V2): void { diff --git a/editor/src/editor/states/Selecting.ts b/editor/src/editor/states/Selecting.ts index 556864e..0b4c181 100644 --- a/editor/src/editor/states/Selecting.ts +++ b/editor/src/editor/states/Selecting.ts @@ -1,17 +1,17 @@ import type { Cx, Tool } from "../Cx"; -import type { V2_ } from "../V2"; +import type { V2 } from "../V2"; import type { State } from "../State"; import { Normal } from "./Normal"; export class Selecting implements State { constructor(private cx: Cx) {} - onMouseUp(_pos: V2_): void { + onMouseUp(_pos: V2): void { this.cx.removeSelectionRect(); this.cx.transitionTo(new Normal(this.cx)); } - onMouseMove(deltaPos: V2_): void { + onMouseMove(deltaPos: V2): void { this.cx.moveSelectionRect(deltaPos); }