😡 component removing 👈

This commit is contained in:
Matei Adriel 2019-06-04 06:59:53 +00:00
parent 6e93a23ec2
commit d7d20b2360
16 changed files with 152 additions and 70 deletions

BIN
src/assets/or_gate.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
src/assets/xor_gate.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -8,8 +8,8 @@
<link rel='stylesheet' href='style.css'>
</head>
<body ondragstart="return false;" ondrop="return false;">
hello world
<body ondragstart="return false;" ondrop="return false;" oncontextmenu="return false">
loading
</body>
</html>

View file

@ -1,7 +1,7 @@
@import "./toastr.scss";
@import "./modal.scss";
$mdc-theme-primary: orange / 2;
$mdc-theme-primary: orange;
$mdc-theme-secondary: #feeae6;
$mdc-theme-on-primary: white;
$mdc-theme-surface: black;

View file

@ -1,23 +0,0 @@
import { Singleton } from "@eix/utils";
import { activationFunction, activationFunctionParam } from "./interfaces"
import { toActivationFunction } from "./toActivation";
@Singleton
export class FunctionStore {
functions = new Map<string, activationFunction>()
private storageKeyword: string
constructor(name="activation") {
this.storageKeyword =`/${name}`
for (let i in localStorage) {
if (i.indexOf(this.storageKeyword) == 0)
this.register(i.substr(this.storageKeyword.length), localStorage[i])
}
}
register(name: string, activation: activationFunctionParam) {
this.functions.set(name, toActivationFunction(activation))
localStorage[`${this.storageKeyword.substr(1)}/${name}`] = activation
}
}

View file

@ -1 +0,0 @@
export * from "./toActivation"

View file

@ -1,4 +0,0 @@
export type activationInput = any[]
export type activationOutput = boolean
export type activationFunctionParam = ( (data:activationInput) => activationOutput ) | string
export type activationFunction = (data:activationInput) => activationOutput

View file

@ -1,8 +0,0 @@
import { activationFunctionParam, activationFunction } from "./interfaces";
export const toActivationFunction = (original: activationFunctionParam) => {
const stringified = (typeof original == "string") ? original : original.toString()
const final = new Function(`return ${stringified}`) as () => activationFunction
return final()
}

View file

@ -11,6 +11,7 @@ import { alertOptions } from "../componentManager/alertOptions";
import { WireManager } from "../wires";
import { runCounter } from "./runCounter";
import { Material } from "./material";
import { manager } from "../../main";
export class Component {
private static store = new ComponentTemplateStore()
@ -76,9 +77,9 @@ export class Component {
this.subscriptions.push(subscription)
})
this.activate()
this.material = new Material(data.material.mode, data.material.data)
this.activate()
}
public dispose() {
@ -110,6 +111,9 @@ export class Component {
}
handleClick(e: MouseEvent) {
console.log(e.button)
if (e.button === 0) {
const mousePosition = Component.screen.getWorldPosition(e.clientX, e.clientY)
this.mouserDelta = this.position.value.map((value, index) =>
@ -122,6 +126,16 @@ export class Component {
this.activate(0)
}
else if (e.button === 2){
manager.components = manager.components.filter(val => val !== this)
manager.wireManager.wires
.filter(val => val.input.of === this || val.output.of === this)
.forEach(val => val.dispose())
manager.wireManager.update.next(true)
manager.update()
}
}
handlePinClick(e: MouseEvent, pin: Pin) {
Component.wireManager.add(pin)
}

View file

@ -11,7 +11,9 @@ export class Material {
private static images: {
[key: string]: string
} = {
and: require("../../../assets/and_gate.jpg")
and: require("../../../assets/and_gate.jpg"),
or: require("../../../assets/or_gate.png"),
xor: require("../../../assets/xor_gate.png")
}
private static cached = new Map()

View file

@ -26,13 +26,13 @@ export class ComponentManager {
public svgs = new Subject<SVGTemplateResult>()
public placeholder = new BehaviorSubject("Create simulation")
public barAlpha = new BehaviorSubject<string>("0");
public wireManager = new WireManager()
private temporaryCommnad = ""
private onTop: Component
private clicked = false
private screen = new Screen()
private wireManager = new WireManager()
private templateStore = new ComponentTemplateStore()
private settings = new Settings()
private standard: {
@ -53,7 +53,7 @@ export class ComponentManager {
private palleteEvent = new KeyboardInput("p")
private shiftEvent = new KeyboardInput("shift")
private refreshEvent = new KeyboardInput("r")
private clearEvent = new KeyboardInput("c")
private clearEvent = new KeyboardInput("delete")
private upEvent = new KeyboardInput("up")
private downEvent = new KeyboardInput("down")
@ -99,6 +99,17 @@ export class ComponentManager {
public gates = this.templateStore.store.lsChanges
public saves = this.store.lsChanges
public file: {
[key: string]: () => void
} = {
clear: () => this.clear(),
clean: () => this.smartClear(),
save: () => this.save(),
refresh: () => this.refresh(),
download: () => download(this,[],[]),
delete: () => this.delete(this.name)
}
constructor() {
runCounter.increase()
@ -158,12 +169,6 @@ export class ComponentManager {
this.inputMode = "command"
this.placeholder.next("Command palette")
}
else if (this.clearEvent.value) {
if (this.shiftEvent.value)
this.clear()
else
this.smartClear()
}
else if (this.saveEvent.value) {
this.save()
}
@ -171,6 +176,12 @@ export class ComponentManager {
this.refresh()
}
}
else if (this.clearEvent.value) {
if (this.shiftEvent.value)
this.clear()
else
this.smartClear()
}
}
})

View file

@ -104,6 +104,32 @@ export class ComponentTemplateStore {
data: "and"
}
})
this.store.set("or", {
inputs: 2,
outputs: 1,
name: "or",
version: "1.0.0",
activation: `
ctx.outputs[0].value = ctx.inputs[0].value || ctx.inputs[1].value
`.trim(),
material: {
mode: "standard_image",
data: "or"
}
})
this.store.set("xor", {
inputs: 2,
outputs: 1,
name: "xor",
version: "1.0.0",
activation: `
ctx.outputs[0].value = (ctx.inputs[0].value || ctx.inputs[1].value) && !(ctx.inputs[0].value && ctx.inputs[1].value)
`.trim(),
material: {
mode: "standard_image",
data: "xor"
}
})
this.store.set("true", {
inputs: 0,
outputs: 1,
@ -161,7 +187,7 @@ export class ComponentTemplateStore {
onclick: `
ctx.outputs[0].memory.value = !ctx.outputs[0].memory.value
if (ctx.outputs[0].memory.value)
ctx.color("#880000")
ctx.color("#550000")
else
ctx.color("red")
`

View file

@ -36,12 +36,16 @@ export const modal = (options: Partial<confirmModalOptions>) => new Promise((res
${content}
</div>
<footer class="mdc-dialog__actions">
<button type="button" class="mdc-button mdc-dialog__button" id="no-${id}">
${(no !== "") ?
html`<button type="button" class="mdc-button mdc-dialog__button" id="no-${id}">
<span class="mdc-button__label">${no}</span>
</button>
<button type="button" class="mdc-button mdc-dialog__button" id="yes-${id}">
</button>` : no
}
${(yes !== "") ?
html`<button type="button" class="mdc-button mdc-dialog__button" id="yes-${id}">
<span class="mdc-button__label">${yes}</span>
</button>
</button>` : yes
}
</footer>
</div>
</div>

View file

@ -11,5 +11,7 @@ export class Wire {
public dispose(){
this.output.unbind(this.input)
this.input.pair = null
this.input.update()
this.output.update()
}
}

View file

@ -51,6 +51,12 @@ export class WireManager {
return true
}
private remove(target: Wire) {
target.dispose()
this.wires = this.wires.filter(val => val !== target)
this.update.next(true)
}
get svg() {
return this.wires.map(val => {
const i = val.input.of
@ -61,6 +67,8 @@ export class WireManager {
y1=${subscribe(i.piny(false,i.outputPins.indexOf(val.input)))}
y2=${subscribe(o.piny(true,o.inputPins.indexOf(val.output)))}
stroke=${subscribe(val.input.svgColor)}
stroke-width=10
@click=${() => this.remove(val)}
>
</line>
`})

View file

@ -2,17 +2,47 @@ import { render, html, svg } from "lit-html"
import { subscribe } from "lit-rx"
import { Screen } from "./common/screen.ts";
import { Component } from "./common/component";
import { FunctionStore } from "./common/activation/activationStore";
import { ComponentManager } from "./common/componentManager";
import { map } from "rxjs/operators";
import { MDCMenu } from '@material/menu';
import { error } from "toastr"
import { modal } from "./common/modals";
const screen = new Screen()
const manager = new ComponentManager()
export const manager = new ComponentManager()
manager.save()
manager.update()
window.onerror = (message: string, url: string, lineNumber: number): boolean => {
error(message,"",{
...manager.alertOptions,
onclick: () => modal({
no: "",
yes: "close",
title: "Error",
content: html`
<table>
<tr>
<td>Url:</td>
<td>${url}</td>
</tr>
<tr>
<td>Message:</td>
<td>${message}</td>
</tr>
<tr>
<td>Line:</td>
<td>${lineNumber}</td>
</tr>
</table>
`
})
})
return true;
};
const handleEvent = <T>(e: T, func: (e: T) => any) => {
if (manager.barAlpha.value == "0")
func(e)
@ -75,6 +105,12 @@ render(html`
<i class="material-icons mdc-list-item__graphic" aria-hidden="true">add</i>
<span class="mdc-list-item__text">Add logic gate</span>
</a>
<a class="mdc-list-item" href="#" id="openFile" @click=${() => {
menus[2].open = true
}}>
<i class="material-icons mdc-list-item__graphic" aria-hidden="true">insert_drive_file</i>
<span class="mdc-list-item__text">File</span>
</a>
</nav>
</div>
</aside>
@ -99,11 +135,26 @@ render(html`
))))}
</ul>
</div>
<div class="mdc-menu mdc-menu-surface mdc-theme--primary-bg mdc-theme--on-primary" id="fileMenu">
<ul class="mdc-list" role="menu" aria-hidden="true" aria-orientation="vertical" tabindex="-1">
${[...Object.keys(manager.file)].sort().map(key => html`
<li class= "mdc-list-item" role = "menuitem" @click=${() => manager.file[key]()}>
<span class="mdc-list-item__text"> ${key} </span>
</li>`
)}
</ul>
</div>
`, document.body)
const menus = [new MDCMenu(document.querySelector('#saveMenu')), new MDCMenu(document.querySelector('#gateMenu'))]
const menus = [
new MDCMenu(document.querySelector('#saveMenu')),
new MDCMenu(document.querySelector('#gateMenu')),
new MDCMenu(document.querySelector('#fileMenu'))
]
menus.forEach(menu => menu.hoistMenuToBody())
menus[0].setAnchorElement(document.querySelector(`#openSimulation`))
menus[1].setAnchorElement(document.querySelector("#openGates"))
menus[2].setAnchorElement(document.querySelector("#openFile"))
manager.update()