add click handler
This commit is contained in:
parent
60e589e689
commit
a889c03929
@ -13,7 +13,7 @@ function App(): ReactElement {
|
||||
<h1>nandsim</h1>
|
||||
<div className="Editor">
|
||||
<Toolbar editor={editor} canvasRef={canvasRef} />
|
||||
<Canvas editor={editor} canvasRef={canvasRef} />
|
||||
<Canvas editor={editor} canvasRef={canvasRef} width={800} height={800} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -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<HTMLCanvasElement | null> };
|
||||
type Props = { editor: Editor; canvasRef: RefObject<HTMLCanvasElement | null>, 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 {
|
||||
<div className="Canvas">
|
||||
<canvas
|
||||
ref={canvasRef}
|
||||
width={1000}
|
||||
height={1000}
|
||||
style={{ width: 1000, height: 1000, backgroundColor: "black" }}
|
||||
width={width}
|
||||
height={height}
|
||||
style={{ width, height, backgroundColor: "black" }}
|
||||
tabIndex={0}
|
||||
onMouseDown={(ev) => {
|
||||
const pos = v2(ev.nativeEvent.offsetX, ev.nativeEvent.offsetY);
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user