delegate handlers
This commit is contained in:
parent
505e869e1f
commit
6ead8c97e2
@ -26,6 +26,20 @@ export class CanvasRenderer implements Renderer {
|
|||||||
g.fillRect(x, y, w, h);
|
g.fillRect(x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strokeRect(
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
w: number,
|
||||||
|
h: number,
|
||||||
|
color: string,
|
||||||
|
lineWidth: number,
|
||||||
|
): void {
|
||||||
|
const { g } = this;
|
||||||
|
g.strokeStyle = color;
|
||||||
|
g.lineWidth = lineWidth;
|
||||||
|
g.strokeRect(x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
fillCirc(x: number, y: number, radius: number, color: string): void {
|
fillCirc(x: number, y: number, radius: number, color: string): void {
|
||||||
const { g } = this;
|
const { g } = this;
|
||||||
g.fillStyle = color;
|
g.fillStyle = color;
|
||||||
@ -40,9 +54,12 @@ export class CanvasRenderer implements Renderer {
|
|||||||
y: number,
|
y: number,
|
||||||
w = data.width,
|
w = data.width,
|
||||||
h = data.height,
|
h = data.height,
|
||||||
|
alpha = 1,
|
||||||
): void {
|
): void {
|
||||||
const { g } = this;
|
const { g } = this;
|
||||||
|
g.globalAlpha = alpha;
|
||||||
g.drawImage(data, x, y, w, h);
|
g.drawImage(data, x, y, w, h);
|
||||||
|
g.globalAlpha = 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
src/grid.ts
20
src/grid.ts
@ -169,6 +169,24 @@ class TransformingRenderer implements Renderer {
|
|||||||
const { r, t: { s, ox, oy } } = this;
|
const { r, t: { s, ox, oy } } = this;
|
||||||
r.fillRect(x * s + ox, y * s + oy, w * s, h * s, color);
|
r.fillRect(x * s + ox, y * s + oy, w * s, h * s, color);
|
||||||
}
|
}
|
||||||
|
strokeRect(
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
w: number,
|
||||||
|
h: number,
|
||||||
|
color: string,
|
||||||
|
lineWidth: number,
|
||||||
|
): void {
|
||||||
|
const { r, t: { s, ox, oy } } = this;
|
||||||
|
r.strokeRect(
|
||||||
|
x * s + ox,
|
||||||
|
y * s + oy,
|
||||||
|
w * s,
|
||||||
|
h * s,
|
||||||
|
color,
|
||||||
|
lineWidth * s,
|
||||||
|
);
|
||||||
|
}
|
||||||
fillCirc(x: number, y: number, radius: number, color: string): void {
|
fillCirc(x: number, y: number, radius: number, color: string): void {
|
||||||
const { r, t: { s, ox, oy } } = this;
|
const { r, t: { s, ox, oy } } = this;
|
||||||
r.fillCirc(x * s + ox, y * s + oy, radius * s, color);
|
r.fillCirc(x * s + ox, y * s + oy, radius * s, color);
|
||||||
@ -179,6 +197,7 @@ class TransformingRenderer implements Renderer {
|
|||||||
y: number,
|
y: number,
|
||||||
w = data.width,
|
w = data.width,
|
||||||
h = data.width,
|
h = data.width,
|
||||||
|
alpha = 1,
|
||||||
): void {
|
): void {
|
||||||
const { r, t: { s, ox, oy } } = this;
|
const { r, t: { s, ox, oy } } = this;
|
||||||
|
|
||||||
@ -188,6 +207,7 @@ class TransformingRenderer implements Renderer {
|
|||||||
y * s + oy,
|
y * s + oy,
|
||||||
w * s,
|
w * s,
|
||||||
h * s,
|
h * s,
|
||||||
|
alpha,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@ export class Painter implements Renderer {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(r: Renderer, x: number, y: number) {
|
render(r: Renderer, x: number, y: number, alpha = 1) {
|
||||||
r.putImage(this.c, x, y, this.c.width, this.c.height);
|
r.putImage(this.c, x, y, this.c.width, this.c.height, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
get width(): number {
|
get width(): number {
|
||||||
@ -31,6 +31,16 @@ export class Painter implements Renderer {
|
|||||||
fillRect(x: number, y: number, w: number, h: number, color: string): void {
|
fillRect(x: number, y: number, w: number, h: number, color: string): void {
|
||||||
this.r.fillRect(x, y, w, h, color);
|
this.r.fillRect(x, y, w, h, color);
|
||||||
}
|
}
|
||||||
|
strokeRect(
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
w: number,
|
||||||
|
h: number,
|
||||||
|
color: string,
|
||||||
|
lineWidth: number,
|
||||||
|
): void {
|
||||||
|
this.r.strokeRect(x, y, w, h, color, lineWidth);
|
||||||
|
}
|
||||||
fillCirc(x: number, y: number, radius: number, color: string): void {
|
fillCirc(x: number, y: number, radius: number, color: string): void {
|
||||||
this.r.fillCirc(x, y, radius, color);
|
this.r.fillCirc(x, y, radius, color);
|
||||||
}
|
}
|
||||||
@ -40,7 +50,8 @@ export class Painter implements Renderer {
|
|||||||
y: number,
|
y: number,
|
||||||
w = data.width,
|
w = data.width,
|
||||||
h = data.height,
|
h = data.height,
|
||||||
|
alpha = 1,
|
||||||
): void {
|
): void {
|
||||||
this.r.putImage(data, x, y, w, h);
|
this.r.putImage(data, x, y, w, h, alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,16 @@ export interface Renderer {
|
|||||||
get height(): N;
|
get height(): N;
|
||||||
clear(color: string): void;
|
clear(color: string): void;
|
||||||
fillRect(x: N, y: N, w: N, h: N, color: string): void;
|
fillRect(x: N, y: N, w: N, h: N, color: string): void;
|
||||||
|
strokeRect(x: N, y: N, w: N, h: N, color: string, lineWidth: number): void;
|
||||||
fillCirc(x: N, y: N, radius: N, color: string): void;
|
fillCirc(x: N, y: N, radius: N, color: string): void;
|
||||||
putImage(data: RendererImage, x: N, y: N, w?: N, h?: N): void;
|
putImage(data: RendererImage, x: N, y: N): void;
|
||||||
|
putImage(data: RendererImage, x: N, y: N, w: N, h: N): void;
|
||||||
|
putImage(
|
||||||
|
data: RendererImage,
|
||||||
|
x: N,
|
||||||
|
y: N,
|
||||||
|
w: N,
|
||||||
|
h: N,
|
||||||
|
alpha: number,
|
||||||
|
): void;
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,10 @@ export class Simulator {
|
|||||||
|
|
||||||
render(r: Renderer) {
|
render(r: Renderer) {
|
||||||
hover: {
|
hover: {
|
||||||
if (this.toolbar.hover(this.mouse.x, this.mouse.y) === "break") {
|
if (this.toolbar.hover() === "break") {
|
||||||
break hover;
|
break hover;
|
||||||
}
|
}
|
||||||
|
document.body.style.cursor = "default";
|
||||||
}
|
}
|
||||||
|
|
||||||
r.clear("black");
|
r.clear("black");
|
||||||
@ -54,6 +55,14 @@ class Toolbar {
|
|||||||
|
|
||||||
this.mouse.addOnPress(() => {
|
this.mouse.addOnPress(() => {
|
||||||
const { x, y } = this.mouse;
|
const { x, y } = this.mouse;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!(x >= 0 && y >= this.lastHeight - 200 && x < this.lastWidth &&
|
||||||
|
y < this.lastHeight)
|
||||||
|
) {
|
||||||
|
return "bubble";
|
||||||
|
}
|
||||||
|
|
||||||
for (const [i, component] of this.previews.entries()) {
|
for (const [i, component] of this.previews.entries()) {
|
||||||
if (
|
if (
|
||||||
x >= i * 128 + 96 - 48 &&
|
x >= i * 128 + 96 - 48 &&
|
||||||
@ -65,7 +74,8 @@ class Toolbar {
|
|||||||
return "stop";
|
return "stop";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "bubble";
|
this.tooltip.deselect();
|
||||||
|
return "stop";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +84,8 @@ class Toolbar {
|
|||||||
this.previews = this.tools as unknown as Component[];
|
this.previews = this.tools as unknown as Component[];
|
||||||
}
|
}
|
||||||
|
|
||||||
hover(x: number, y: number): "continue" | "break" {
|
hover(): "continue" | "break" {
|
||||||
|
const { x, y } = this.mouse;
|
||||||
for (const [i, component] of this.previews.entries()) {
|
for (const [i, component] of this.previews.entries()) {
|
||||||
if (
|
if (
|
||||||
x >= i * 128 + 96 - 48 &&
|
x >= i * 128 + 96 - 48 &&
|
||||||
@ -83,6 +94,7 @@ class Toolbar {
|
|||||||
y < this.lastHeight - 100 + component.height * 32 + 32
|
y < this.lastHeight - 100 + component.height * 32 + 32
|
||||||
) {
|
) {
|
||||||
this.hoveringComponentIdx = i;
|
this.hoveringComponentIdx = i;
|
||||||
|
document.body.style.cursor = "pointer";
|
||||||
return "break";
|
return "break";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,6 +108,14 @@ class Toolbar {
|
|||||||
|
|
||||||
r.fillRect(0, r.height - 200, r.width, 200, "#aaa");
|
r.fillRect(0, r.height - 200, r.width, 200, "#aaa");
|
||||||
for (const [i, component] of this.previews.entries()) {
|
for (const [i, component] of this.previews.entries()) {
|
||||||
|
r.strokeRect(
|
||||||
|
i * 128 + 96 - 48,
|
||||||
|
r.height - 100 - 48,
|
||||||
|
96,
|
||||||
|
96,
|
||||||
|
"#777",
|
||||||
|
1,
|
||||||
|
);
|
||||||
if (i === this.hoveringComponentIdx) {
|
if (i === this.hoveringComponentIdx) {
|
||||||
r.fillRect(
|
r.fillRect(
|
||||||
i * 128 + 96 - 48,
|
i * 128 + 96 - 48,
|
||||||
@ -113,6 +133,8 @@ class Toolbar {
|
|||||||
class Tooltip {
|
class Tooltip {
|
||||||
private selectedComponent?: Component;
|
private selectedComponent?: Component;
|
||||||
|
|
||||||
|
private shouldHover = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private circuit: Circuit,
|
private circuit: Circuit,
|
||||||
public mouse: Mouse,
|
public mouse: Mouse,
|
||||||
@ -125,18 +147,37 @@ class Tooltip {
|
|||||||
const x = Math.floor(this.mouse.x / 32);
|
const x = Math.floor(this.mouse.x / 32);
|
||||||
const y = Math.floor(this.mouse.y / 32);
|
const y = Math.floor(this.mouse.y / 32);
|
||||||
this.circuit.place(this.selectedComponent, x, y);
|
this.circuit.place(this.selectedComponent, x, y);
|
||||||
this.selectedComponent = undefined;
|
|
||||||
return "stop";
|
return "stop";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hover(): "continue" | "break" {
|
||||||
|
if (!this.selectedComponent) {
|
||||||
|
return "continue";
|
||||||
|
}
|
||||||
|
const x = Math.floor(this.mouse.x / 32);
|
||||||
|
const y = Math.floor(this.mouse.y / 32);
|
||||||
|
if (!this.circuit.placeIsOccupied(x, y)) {
|
||||||
|
this.shouldHover = true;
|
||||||
|
return "break";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "continue";
|
||||||
|
}
|
||||||
|
|
||||||
render(r: Renderer): void {
|
render(r: Renderer): void {
|
||||||
this.selectedComponent?.render(r, this.mouse.x, this.mouse.y);
|
const x = Math.floor(this.mouse.x / 32);
|
||||||
|
const y = Math.floor(this.mouse.y / 32);
|
||||||
|
this.selectedComponent?.renderTransparent(r, x * 32 + 16, y * 32 + 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
select(component: Component): void {
|
select(component: Component): void {
|
||||||
this.selectedComponent = component;
|
this.selectedComponent = component;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deselect(): void {
|
||||||
|
this.selectedComponent = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type PlacedComponent = {
|
type PlacedComponent = {
|
||||||
@ -173,6 +214,14 @@ class Circuit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
placeIsOccupied(x: number, y: number): boolean {
|
||||||
|
return this.components.some((c) => c.x == x && c.y == y);
|
||||||
|
}
|
||||||
|
|
||||||
|
hover(): "continue" | "break" {
|
||||||
|
return "continue";
|
||||||
|
}
|
||||||
|
|
||||||
place(component: Component, x: number, y: number): void {
|
place(component: Component, x: number, y: number): void {
|
||||||
this.components.push({ component, x, y });
|
this.components.push({ component, x, y });
|
||||||
}
|
}
|
||||||
@ -188,6 +237,7 @@ interface Component {
|
|||||||
get width(): number;
|
get width(): number;
|
||||||
get height(): number;
|
get height(): number;
|
||||||
render(r: Renderer, x: number, y: number): void;
|
render(r: Renderer, x: number, y: number): void;
|
||||||
|
renderTransparent(r: Renderer, x: number, y: number): void;
|
||||||
click?(x: number, y: number): void;
|
click?(x: number, y: number): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,6 +273,11 @@ class SwitchComponent implements Component, ComponentFactory {
|
|||||||
graphic.render(r, x - 48, y - 32);
|
graphic.render(r, x - 48, y - 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderTransparent(r: Renderer, x: number, y: number): void {
|
||||||
|
const graphic = this.switchOn ? this.graphicOn : this.graphicOff;
|
||||||
|
graphic.render(r, x - 48, y - 32, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
click(x: number, y: number): void {
|
click(x: number, y: number): void {
|
||||||
const onButton = Math.sqrt(
|
const onButton = Math.sqrt(
|
||||||
(x - 16) ** 2 + (y - 16) ** 2,
|
(x - 16) ** 2 + (y - 16) ** 2,
|
||||||
@ -261,4 +316,9 @@ class LedComponent implements Component, ComponentFactory {
|
|||||||
const graphic = this.switchOn ? this.graphicOn : this.graphicOff;
|
const graphic = this.switchOn ? this.graphicOn : this.graphicOff;
|
||||||
graphic.render(r, x - 48, y - 32);
|
graphic.render(r, x - 48, y - 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderTransparent(r: Renderer, x: number, y: number): void {
|
||||||
|
const graphic = this.switchOn ? this.graphicOn : this.graphicOff;
|
||||||
|
graphic.render(r, x - 48, y - 32, 0.5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user