refactor states
This commit is contained in:
parent
bdf4a01e7f
commit
2a172f687c
@ -1,15 +1,12 @@
|
||||
import { Board, ComponentRepo } from "./Board";
|
||||
import { Renderer } from "./Renderer";
|
||||
import type { State } from "./State";
|
||||
import { Normal } from "./states/Normal";
|
||||
import { Panning } from "./states/Panning";
|
||||
import { Placing } from "./states/Placing";
|
||||
import * as states from "./states";
|
||||
import { v2, V2 } from "./V2";
|
||||
|
||||
export class Cx {
|
||||
public offset = v2(0, 0);
|
||||
private renderNeeded = false;
|
||||
private state = new Normal(this) as State;
|
||||
private state = new states.Normal(this) as states.State;
|
||||
private updateActions: (() => void)[] = [];
|
||||
|
||||
private selectionBox: SelectionBox | null = null;
|
||||
@ -57,17 +54,17 @@ export class Cx {
|
||||
selectTool(tool: Tool) {
|
||||
switch (tool) {
|
||||
case "pan":
|
||||
this.transitionTo(new Panning(this));
|
||||
this.transitionTo(new states.Panning(this));
|
||||
break;
|
||||
case "input":
|
||||
case "output":
|
||||
case "and":
|
||||
case "or":
|
||||
case "not":
|
||||
this.transitionTo(new Placing(this, tool));
|
||||
this.transitionTo(new states.Placing(this, tool));
|
||||
break;
|
||||
default:
|
||||
this.transitionTo(new Normal(this));
|
||||
this.transitionTo(new states.Normal(this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +79,7 @@ export class Cx {
|
||||
);
|
||||
}
|
||||
|
||||
transitionTo(newState: State) {
|
||||
transitionTo(newState: states.State) {
|
||||
this.state.leaveState?.();
|
||||
this.state = newState;
|
||||
this.state.enterState?.();
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
import type { Tool } from "./Cx";
|
||||
import type { V2 } from "./V2";
|
||||
|
||||
export interface State {
|
||||
enterState?(): void;
|
||||
leaveState?(): void;
|
||||
onMouseDown?(pos: V2): void;
|
||||
onMouseUp?(pos: V2): void;
|
||||
onMouseMove?(deltaPos: V2, pos: V2): void;
|
||||
onKeyDown?(key: string): void;
|
||||
onKeyUp?(key: string): void;
|
||||
selectedTool?(): Tool | null;
|
||||
}
|
||||
151
editor/src/editor/states.ts
Normal file
151
editor/src/editor/states.ts
Normal file
@ -0,0 +1,151 @@
|
||||
import type { ComponentDef } from "./Board";
|
||||
import type { Cx, Tool } from "./Cx";
|
||||
import { v2, type V2 } from "./V2";
|
||||
|
||||
export interface State {
|
||||
enterState?(): void;
|
||||
leaveState?(): void;
|
||||
onMouseDown?(pos: V2): void;
|
||||
onMouseUp?(pos: V2): void;
|
||||
onMouseMove?(deltaPos: V2, pos: V2): void;
|
||||
onKeyDown?(key: string): void;
|
||||
onKeyUp?(key: string): void;
|
||||
selectedTool?(): Tool | null;
|
||||
}
|
||||
|
||||
export class Normal implements State {
|
||||
constructor(private cx: Cx) {}
|
||||
|
||||
onMouseDown(pos: V2): void {
|
||||
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 SelectingBox(this.cx));
|
||||
}
|
||||
}
|
||||
|
||||
onMouseMove(_deltaPos: V2, pos: V2): void {
|
||||
this.cx.board.updateMouseHover(pos.sub(this.cx.offset));
|
||||
this.cx.setRenderNeeded();
|
||||
}
|
||||
|
||||
onKeyDown(key: string): void {
|
||||
if (key === "Shift") {
|
||||
this.cx.transitionTo(new Panning(this.cx));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
selectedTool(): Tool | null {
|
||||
return "select";
|
||||
}
|
||||
}
|
||||
|
||||
export class Panning implements State {
|
||||
private dragging = false;
|
||||
|
||||
constructor(private cx: Cx) {}
|
||||
|
||||
onMouseDown(_pos: V2): void {
|
||||
this.dragging = true;
|
||||
}
|
||||
|
||||
onMouseUp(_pos: V2): void {
|
||||
this.dragging = false;
|
||||
}
|
||||
|
||||
onMouseMove(deltaPos: V2): void {
|
||||
if (this.dragging) {
|
||||
this.cx.moveOffset(deltaPos);
|
||||
}
|
||||
}
|
||||
|
||||
onKeyDown(key: string): void {
|
||||
if (key === "Escape") {
|
||||
this.cx.transitionTo(new Normal(this.cx));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
onKeyUp(key: string): void {
|
||||
if (key === "Shift") {
|
||||
this.cx.transitionTo(new Normal(this.cx));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
selectedTool(): Tool | null {
|
||||
return "pan";
|
||||
}
|
||||
}
|
||||
|
||||
export class Placing implements State {
|
||||
private compDef: ComponentDef;
|
||||
|
||||
constructor(
|
||||
private cx: Cx,
|
||||
private tool: Tool,
|
||||
) {
|
||||
this.compDef = this.cx.componentRepo.get(this.tool);
|
||||
}
|
||||
|
||||
enterState(): void {
|
||||
this.cx.addComponentPlacer(v2(0, 0), this.compDef.size);
|
||||
}
|
||||
|
||||
leaveState(): void {
|
||||
this.cx.removeComponentPlacer();
|
||||
}
|
||||
|
||||
onMouseDown(pos: V2): void {
|
||||
const boardPos = this.cx.canvasPosToBoard(pos);
|
||||
if (this.cx.board.canPlaceComponent(this.compDef, boardPos)) {
|
||||
this.cx.board.placeComponent(this.compDef, boardPos);
|
||||
this.cx.transitionTo(new Normal(this.cx));
|
||||
}
|
||||
}
|
||||
|
||||
onMouseMove(_deltaPos: V2, pos: V2): void {
|
||||
this.cx.setComponentPlacerPos(pos);
|
||||
}
|
||||
|
||||
onKeyDown(key: string): void {
|
||||
if (key === "Escape") {
|
||||
this.cx.transitionTo(new Normal(this.cx));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
selectedTool(): Tool | null {
|
||||
return this.tool;
|
||||
}
|
||||
}
|
||||
|
||||
export class Selecting implements State {
|
||||
constructor(private cx: Cx) {}
|
||||
}
|
||||
|
||||
export class SelectingBox implements State {
|
||||
constructor(private cx: Cx) {}
|
||||
|
||||
onMouseUp(_pos: V2): void {
|
||||
this.cx.removeSelectionRect();
|
||||
this.cx.transitionTo(new Normal(this.cx));
|
||||
}
|
||||
|
||||
onMouseMove(deltaPos: V2): void {
|
||||
this.cx.moveSelectionRect(deltaPos);
|
||||
}
|
||||
|
||||
selectedTool(): Tool | null {
|
||||
return "select";
|
||||
}
|
||||
}
|
||||
@ -1,41 +0,0 @@
|
||||
import type { Cx, Tool } from "../Cx";
|
||||
import type { V2 } from "../V2";
|
||||
import type { State } from "../State";
|
||||
import { Panning } from "./Panning";
|
||||
import { SelectingBox } from "./SelectingBox";
|
||||
|
||||
export class Normal implements State {
|
||||
constructor(private cx: Cx) {}
|
||||
|
||||
onMouseDown(pos: V2): void {
|
||||
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 SelectingBox(this.cx));
|
||||
}
|
||||
}
|
||||
|
||||
onMouseMove(_deltaPos: V2, pos: V2): void {
|
||||
this.cx.board.updateMouseHover(pos.sub(this.cx.offset));
|
||||
this.cx.setRenderNeeded();
|
||||
}
|
||||
|
||||
onKeyDown(key: string): void {
|
||||
if (key === "Shift") {
|
||||
this.cx.transitionTo(new Panning(this.cx));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
selectedTool(): Tool | null {
|
||||
return "select";
|
||||
}
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
import type { Cx, Tool } from "../Cx";
|
||||
import type { V2_ } from "../V2";
|
||||
import type { State } from "../State";
|
||||
import { Normal } from "./Normal";
|
||||
|
||||
export class Panning implements State {
|
||||
private dragging = false;
|
||||
|
||||
constructor(private cx: Cx) {}
|
||||
|
||||
onMouseDown(_pos: V2_): void {
|
||||
this.dragging = true;
|
||||
}
|
||||
|
||||
onMouseUp(_pos: V2_): void {
|
||||
this.dragging = false;
|
||||
}
|
||||
|
||||
onMouseMove(deltaPos: V2_): void {
|
||||
if (this.dragging) {
|
||||
this.cx.moveOffset(deltaPos);
|
||||
}
|
||||
}
|
||||
|
||||
onKeyDown(key: string): void {
|
||||
if (key === "Escape") {
|
||||
this.cx.transitionTo(new Normal(this.cx));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
onKeyUp(key: string): void {
|
||||
if (key === "Shift") {
|
||||
this.cx.transitionTo(new Normal(this.cx));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
selectedTool(): Tool | null {
|
||||
return "pan";
|
||||
}
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
import { type Cx, type Tool } from "../Cx";
|
||||
import { V2, v2 } from "../V2";
|
||||
import type { State } from "../State";
|
||||
import { Normal } from "./Normal";
|
||||
import type { ComponentDef } from "../Board";
|
||||
|
||||
export class Placing implements State {
|
||||
private compDef: ComponentDef;
|
||||
|
||||
constructor(
|
||||
private cx: Cx,
|
||||
private tool: Tool,
|
||||
) {
|
||||
this.compDef = this.cx.componentRepo.get(this.tool);
|
||||
}
|
||||
|
||||
enterState(): void {
|
||||
this.cx.addComponentPlacer(v2(0, 0), this.compDef.size);
|
||||
}
|
||||
|
||||
leaveState(): void {
|
||||
this.cx.removeComponentPlacer();
|
||||
}
|
||||
|
||||
onMouseDown(pos: V2): void {
|
||||
const boardPos = this.cx.canvasPosToBoard(pos);
|
||||
if (this.cx.board.canPlaceComponent(this.compDef, boardPos)) {
|
||||
this.cx.board.placeComponent(this.compDef, boardPos);
|
||||
this.cx.transitionTo(new Normal(this.cx));
|
||||
}
|
||||
}
|
||||
|
||||
onMouseMove(_deltaPos: V2, pos: V2): void {
|
||||
this.cx.setComponentPlacerPos(pos);
|
||||
}
|
||||
|
||||
onKeyDown(key: string): void {
|
||||
if (key === "Escape") {
|
||||
this.cx.transitionTo(new Normal(this.cx));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
selectedTool(): Tool | null {
|
||||
return this.tool;
|
||||
}
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
import type { Cx } from "../Cx";
|
||||
import type { State } from "../State";
|
||||
|
||||
export class Selecting implements State {
|
||||
constructor(private cx: Cx) {}
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
import type { Cx, Tool } from "../Cx";
|
||||
import type { V2 } from "../V2";
|
||||
import type { State } from "../State";
|
||||
import { Normal } from "./Normal";
|
||||
|
||||
export class SelectingBox implements State {
|
||||
constructor(private cx: Cx) {}
|
||||
|
||||
onMouseUp(_pos: V2): void {
|
||||
this.cx.removeSelectionRect();
|
||||
this.cx.transitionTo(new Normal(this.cx));
|
||||
}
|
||||
|
||||
onMouseMove(deltaPos: V2): void {
|
||||
this.cx.moveSelectionRect(deltaPos);
|
||||
}
|
||||
|
||||
selectedTool(): Tool | null {
|
||||
return "select";
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user