}
export interface InitialisationContext {
diff --git a/src/modules/logic-gates/components/LogicGateModal.tsx b/src/modules/logic-gates/components/LogicGateModal.tsx
index 15e35f7..4504989 100644
--- a/src/modules/logic-gates/components/LogicGateModal.tsx
+++ b/src/modules/logic-gates/components/LogicGateModal.tsx
@@ -53,8 +53,10 @@ const LogicGateModal = () => {
{
+ onClick={e => {
addGate(renderer, name)
+
+ e.stopPropagation()
}}
>
diff --git a/src/modules/saving/constants.ts b/src/modules/saving/constants.ts
index af1ecc4..e258fbd 100644
--- a/src/modules/saving/constants.ts
+++ b/src/modules/saving/constants.ts
@@ -9,7 +9,7 @@ export const baseTemplates: DeepPartial[] = [
},
material: {
type: 'image',
- value: require('../../assets/and_gate')
+ fill: require('../../assets/and')
},
code: {
activation: `context.set(0, context.get(0) && context.get(1))`
@@ -21,13 +21,31 @@ export const baseTemplates: DeepPartial[] = [
},
info: ['https://en.wikipedia.org/wiki/AND_gate']
},
+ {
+ metadata: {
+ name: 'nand'
+ },
+ material: {
+ type: 'image',
+ fill: require('../../assets/nand')
+ },
+ code: {
+ activation: `context.set(0, !context.get(0) || !context.get(1))`
+ },
+ pins: {
+ inputs: {
+ count: 2
+ }
+ },
+ info: ['https://en.wikipedia.org/wiki/NAND_gate']
+ },
{
metadata: {
name: 'or'
},
material: {
type: 'image',
- value: require('../../assets/or_gate.png')
+ fill: require('../../assets/or')
},
code: {
activation: `context.set(0, context.get(0) || context.get(1))`
@@ -45,7 +63,7 @@ export const baseTemplates: DeepPartial[] = [
},
material: {
type: 'image',
- value: require('../../assets/nor_gate.png')
+ fill: require('../../assets/nor')
},
code: {
activation: `context.set(0, !(context.get(0) || context.get(1)))`
@@ -63,7 +81,7 @@ export const baseTemplates: DeepPartial[] = [
},
material: {
type: 'image',
- value: require('../../assets/xor_gate')
+ fill: require('../../assets/xor')
},
code: {
activation: `
@@ -80,12 +98,36 @@ export const baseTemplates: DeepPartial[] = [
}
}
},
+ {
+ metadata: {
+ name: 'xnor'
+ },
+ material: {
+ type: 'image',
+ fill: require('../../assets/xnor')
+ },
+ code: {
+ activation: `
+ const a = context.get(0)
+ const b = context.get(1)
+ const c = (a && b) || !(a || b)
+
+ context.set(0, c)`
+ },
+ info: ['https://en.wikipedia.org/wiki/XNOR_gate'],
+ pins: {
+ inputs: {
+ count: 2
+ }
+ }
+ },
{
metadata: {
name: 'not'
},
material: {
- value: 'red'
+ type: 'image',
+ fill: require('../../assets/not')
},
code: {
activation: `context.set(0, !context.get(0))`
@@ -97,7 +139,14 @@ export const baseTemplates: DeepPartial[] = [
name: 'button'
},
material: {
- value: 'red'
+ fill: '#D32F2E',
+ stroke: {
+ normal: '#AB8C31',
+ active: '#7EF813'
+ },
+ colors: {
+ pressed: '#7D1313'
+ }
},
code: {
onClick: `
@@ -105,7 +154,7 @@ export const baseTemplates: DeepPartial[] = [
const state = !old
context.set(0, state)
- context.color(old ? 'red' : '#550000')
+ context.color(old ? context.colors.main : context.colors.pressed)
context.memory.state = state
`
@@ -128,11 +177,19 @@ export const baseTemplates: DeepPartial[] = [
radius: 50
},
material: {
- value: 'white'
+ fill: '#1C1C1C',
+ stroke: {
+ normal: '#3C3C3C'
+ },
+ colors: {
+ active: '#C6FF00'
+ }
},
code: {
activation: `
- context.color(context.get(0) ? 'yellow' : 'white')
+ const { main, active } = context.colors
+
+ context.color(context.get(0) ? active : main)
`
},
integration: {
diff --git a/src/modules/simulation/classes/Gate.ts b/src/modules/simulation/classes/Gate.ts
index c3c7456..4b2e9a0 100644
--- a/src/modules/simulation/classes/Gate.ts
+++ b/src/modules/simulation/classes/Gate.ts
@@ -62,6 +62,10 @@ export class Gate {
this.transform.scale = this.template.shape.scale
+ if (this.template.material.type === 'color') {
+ this.template.material.colors.main = this.template.material.fill
+ }
+
this.functions.activation = toFunction(
this.template.code.activation,
'context'
@@ -84,7 +88,7 @@ export class Gate {
)
if (this.template.material.type === 'image') {
- ImageStore.set(this.template.material.value)
+ ImageStore.set(this.template.material.fill)
}
this.id = id !== undefined ? id : idStore.generate()
@@ -223,10 +227,13 @@ export class Gate {
memory: this.memory,
color: (color: string) => {
if (this.template.material.type === 'color') {
- this.template.material.value = color
+ this.template.material.fill = color
}
},
- enviroment: this.env
+ enviroment: this.env,
+ colors: {
+ ...this.template.material.colors
+ }
}
}
diff --git a/src/modules/simulation/constants.ts b/src/modules/simulation/constants.ts
index aaaa637..d5db891 100644
--- a/src/modules/simulation/constants.ts
+++ b/src/modules/simulation/constants.ts
@@ -6,7 +6,12 @@ export const DefaultGateTemplate: GateTemplate = {
},
material: {
type: 'color',
- value: 'blue'
+ fill: 'blue',
+ stroke: {
+ active: '#76FF02',
+ normal: '#3FC4FF'
+ },
+ colors: {}
},
pins: {
inputs: {
diff --git a/src/modules/simulation/types/GateTemplate.ts b/src/modules/simulation/types/GateTemplate.ts
index 1759811..95f6441 100644
--- a/src/modules/simulation/types/GateTemplate.ts
+++ b/src/modules/simulation/types/GateTemplate.ts
@@ -7,7 +7,12 @@ export interface PinCount {
export interface Material {
type: 'color' | 'image'
- value: string
+ fill: string
+ stroke: {
+ active: string
+ normal: string
+ }
+ colors: Record
}
export interface Shape {
diff --git a/src/modules/simulationRenderer/helpers/renderGate.ts b/src/modules/simulationRenderer/helpers/renderGate.ts
index 1854d36..5d44069 100644
--- a/src/modules/simulationRenderer/helpers/renderGate.ts
+++ b/src/modules/simulationRenderer/helpers/renderGate.ts
@@ -13,16 +13,19 @@ export const renderGate = (
renderer: SimulationRenderer,
gate: Gate
) => {
- renderPins(ctx, renderer, gate)
+ const { active, normal } = gate.template.material.stroke
- if (
+ const selected =
(renderer.mouseState >> 2 &&
- gatesInSelection(renderer.selectedArea, [gate]).length) ||
+ !!gatesInSelection(renderer.selectedArea, [gate]).length) ||
idIsSelected(renderer, gate.id)
- ) {
- ctx.strokeStyle = renderer.options.gates.gateStroke.active
+
+ renderPins(ctx, renderer, gate, selected)
+
+ if (selected) {
+ ctx.strokeStyle = active
} else {
- ctx.strokeStyle = renderer.options.gates.gateStroke.normal
+ ctx.strokeStyle = normal
}
ctx.lineWidth = renderer.options.gates.gateStroke.width
@@ -41,7 +44,7 @@ export const renderGate = (
if (gate.template.material.type === 'image') {
roundImage(
ctx,
- ImageStore.get(gate.template.material.value),
+ ImageStore.get(gate.template.material.fill),
...renderingParameters
)
}
@@ -49,7 +52,7 @@ export const renderGate = (
roundRect(ctx, ...renderingParameters)
if (gate.template.material.type === 'color') {
- ctx.fillStyle = gate.template.material.value
+ ctx.fillStyle = gate.template.material.fill
ctx.fill()
}
diff --git a/src/modules/simulationRenderer/helpers/renderPins.ts b/src/modules/simulationRenderer/helpers/renderPins.ts
index c872069..7835691 100644
--- a/src/modules/simulationRenderer/helpers/renderPins.ts
+++ b/src/modules/simulationRenderer/helpers/renderPins.ts
@@ -7,21 +7,26 @@ import { pinFill } from './pinFill'
export const renderPins = (
ctx: CanvasRenderingContext2D,
renderer: SimulationRenderer,
- gate: Gate
+ gate: Gate,
+ selected: boolean
) => {
ctx.save()
const {
connectionLength,
pinRadius,
- pinStrokeColor,
pinStrokeWidth
} = renderer.options.gates
const relativeTransform = useTransform(ctx, gate.transform)
- ctx.strokeStyle = pinStrokeColor
ctx.lineWidth = pinStrokeWidth
+ if (selected) {
+ ctx.strokeStyle = gate.template.material.stroke.active
+ } else {
+ ctx.strokeStyle = renderer.options.gates.pinStrokeColor
+ }
+
for (const pin of gate.pins) {
ctx.fillStyle = pinFill(renderer, pin.value)