Skip to content

Commit a953d83

Browse files
authored
V 0.7
1 parent 1aa04e9 commit a953d83

13 files changed

+283
-272
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ Make a computer program!
99
- Delete a gate by dragging it to the right hand side, or by selecting it and pressing `delete`.
1010
- Create new gates by pressing the create button, and naming the gate and specifying the colour.
1111
- The colour of the LEDs can be cycled by pressing the `space bar`.
12-
- Press `control and S` to save, `control and L` to load. The same thing can be done by clicking on the respective buttons.
12+
- Press `control and S` to save. The same thing can be done by clicking on the respective button.
1313
- `Left click` on a wire to delete.
1414

1515
Based on a [video series](https://youtu.be/QZwneRb-zqA?feature=shared) by Sebastian Lague. Just wanted to see what it will look like in JavaScript.
16-
I'm planning to add more stuff like a gate filter in the future. Might also be cool to have a pre-built binary - base 10 system.
16+
I'm planning to add more stuff like a gate filter in the future. Might also be cool to have a pre-built binary - base 10 system. SR latches still aren't supported.
1717

18-
Link to: [Github Pages](https://flippont.github.io/simple-program-editor/)
18+
Link to: [Github Pages](https://flippont.github.io/simple-program-editor/)

index.html

+10-22
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,19 @@
55
<meta charset="UTF-8">
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
77
<title>Simple Program Editor</title>
8+
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🧬</text></svg>">
89
</head>
910

1011
<body>
1112
<link rel="stylesheet" href="./src/styles/style.css">
1213

13-
<div id=popUp>
14-
<div class="modal-content">
15-
<input type="text" id=nameInput placeholder="Gate name">
16-
<div id=colourPickerWrapper>
17-
<input type="color" id=colourInput name=head value=#e66465 onchange="colourValue = this.value"/>
18-
<span class="colourPreview">Colour Preview</span>
19-
</div>
20-
<div class="buttonCont">
21-
<button id=cancelButton onclick="closePopUp()">Cancel</button>
22-
<button id=mainButton onclick="createNewBlock();">Save</button>
23-
</div>
24-
</div>
25-
</div>
14+
<div id=loadMenu class="hidden"></div>
15+
<input id=titleInput class="hidden" type="text">
2616
<canvas id=g></canvas>
2717
<div id=debug>
28-
<p>
29-
X Position: <span id=xPos></span>, Y Position: <span id=yPos></span>
30-
</p>
31-
<p>
32-
Inputs: <span id=inputDiv></span>, Outputs: <span id=outputDiv></span>
33-
</p>
34-
<p>
35-
Value: <span id=valueDiv></span>
36-
</p>
18+
<p>X Position: <span id=xPos></span>, Y Position: <span id=yPos></span></p>
19+
<p>Inputs: <span id=inputDiv></span>, Outputs: <span id=outputDiv></span></p>
20+
<p>Value: <span id=valueDiv></span></p>
3721
</div>
3822
<script src="./src/script/index.js"></script>
3923
<script src="./src/script/globals.js"></script>
@@ -45,14 +29,18 @@
4529
<script src="./src/script/entities/block.js"></script>
4630
<script src="./src/script/entities/wireHandle.js"></script>
4731
<script src="./src/script/entities/scrollbar.js"></script>
32+
<script src="./src/script/entities/popup.js"></script>
4833
<script src="./src/script/entities/select.js"></script>
4934
<script src="./src/script/entities/segment.js"></script>
5035
<script src="./src/script/entities/LED.js"></script>
5136
<script src="./src/script/entities/default.js"></script>
5237
<script src="./src/script/entities/cursor.js"></script>
5338
<script src="./src/script/entities/sidebar.js"></script>
5439
<script src="./src/script/entities/button.js"></script>
40+
41+
<script src="./src/script/scenes.js"></script>
5542
<script src="./src/script/engine.js"></script>
43+
5644
</body>
5745

5846
</html>

src/script/engine.js

+8-19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
add(new SideBar())
21
canvasPrototype.wrap = function(f) {
32
const { resolveColor } = this;
43
this.save();
@@ -18,23 +17,6 @@ function clearBlocks() {
1817
})
1918
}
2019

21-
function generateBlocksArray() {
22-
let blocks = Array.from(category("blocks"));
23-
let returnArray = []
24-
for(let i=0; i<blocks.length; i++) {
25-
returnArray.push({
26-
"x": Math.floor(blocks[i].x),
27-
"y": Math.floor(blocks[i].y),
28-
"data": {
29-
"inputs": blocks[i].data.inputs,
30-
"outputs": blocks[i].data.outputs
31-
},
32-
"type": blocks[i].type
33-
})
34-
}
35-
return returnArray
36-
}
37-
3820
function add(entity) {
3921
if (entities.has(entity)) return;
4022
entities.add(entity)
@@ -63,10 +45,16 @@ function draw() {
6345
//draw stuff
6446
ctx.fillStyle = "#aaa";
6547
ctx.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
48+
49+
if(html[screen].draw){
50+
html[screen].draw()
51+
}
52+
6653
ctx.textAlign = "right"
6754
ctx.font = "bold 15px Arial"
6855
ctx.fillStyle = "#000";
6956
let y = CANVAS_HEIGHT;
57+
7058
for (const line of [
7159
(DEBUG) ? ("FPS: " + ~~(1 / elapsed)) : "",
7260
(DEBUG) ? ("Entities: " + sortedEntities.length) : "",
@@ -90,4 +78,5 @@ function draw() {
9078
}
9179
}
9280

93-
requestAnimationFrame(draw)
81+
requestAnimationFrame(draw)
82+
changeScene(screen)

src/script/entities/block.js

+51-45
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,10 @@ class Block extends Entity {
2727
}
2828

2929
run() {
30+
let popUp = Array.from(category("popup"));
31+
if(popUp[0]) return
32+
3033
let evaluate = Array.from(category("blocks"));
31-
32-
if(!MOUSE_DOWN && this.x < 220) {
33-
this.destroy()
34-
}
3534
// Convert inputs to index
3635
if(this.type === "input") {
3736
if (DOWN[32] && !this.toggled && this.hovered) {
@@ -41,14 +40,14 @@ class Block extends Entity {
4140
if (!DOWN[32]) {
4241
this.toggled = false;
4342
}
44-
this.changeStateBelow()
43+
} else {
44+
this.loopStates()
4545
}
4646

4747
this.hovered = false
4848
this.index = evaluate.indexOf(this)
4949

5050
this.mouseOver()
51-
this.checkInputValid()
5251
// Mouse down check
5352
if(MOUSE_DOWN) {
5453
if(holding != (this.index + 1)) return
@@ -73,6 +72,24 @@ class Block extends Entity {
7372
this.layer = 20;
7473
holding = -1;
7574
}
75+
if(!MOUSE_DOWN && this.x < 220) {
76+
this.destroy()
77+
}
78+
}
79+
80+
loopStates() {
81+
let evaluate = Array.from(category("blocks"));
82+
let newInputs = []
83+
// Gather inputs
84+
for (let k = 0; k < this.data.inputs.length; k++) {
85+
newInputs.push((this.data.inputs[k] && this.data.inputs[k][0] != -1) ? evaluate[this.data.inputs[k][0]].currentValue[this.data.inputs[k][1]] : 0)
86+
if(this.type == "segment") {
87+
this.currentValue[k] = newInputs[k]
88+
}
89+
}
90+
if(this.type != "segment") {
91+
this.changeState(newInputs)
92+
}
7693
}
7794

7895
checkInputValid() {
@@ -81,25 +98,21 @@ class Block extends Entity {
8198
for(let i=0; i<this.data.inputs.length; i++) {
8299
if(evaluate[this.data.inputs[i][0]] == undefined) {
83100
this.data.inputs[i] = [-1]
84-
if(this.type != "output") {
85-
if(this.type != "input") {
86-
this.currentValue[i] = 0;
87-
} else {
88-
this.currentValue[0] = 1;
89-
}
101+
if(this.type != "input") {
102+
this.currentValue[i] = 0;
103+
} else {
104+
this.currentValue[0] = 1;
90105
}
91106
}
92107
}
93108
for(let i=0; i<this.data.outputs.length; i++) {
94109
if(evaluate[this.data.outputs[i][0]] == undefined) {
95110
this.data.outputs[i] = [];
96-
if(this.type != "output") {
97-
if(this.type != "input") {
98-
this.currentValue[i] = 0;
99-
} else {
100-
this.currentValue[i] = 1;
101-
}
102-
}
111+
if(this.type != "input") {
112+
this.currentValue[i] = 0;
113+
} else {
114+
this.currentValue[i] = 1;
115+
}
103116
}
104117
}
105118
}
@@ -110,17 +123,7 @@ class Block extends Entity {
110123
for(let j=0; j<this.data.outputs[i].length; j++) {
111124
let subject = evaluate[this.data.outputs[i][j]];
112125
if(subject == undefined) return
113-
let newInputs = []
114-
// Gather inputs
115-
for (let k = 0; k < subject.data.inputs.length; k++) {
116-
newInputs.push((subject.data.inputs[k] && subject.data.inputs[k][0] != -1) ? evaluate[subject.data.inputs[k][0]].currentValue[subject.data.inputs[k][1]] : 0)
117-
if(subject.type == "segment") {
118-
subject.currentValue[k] = newInputs[k]
119-
}
120-
}
121-
if(subject.type != "segment") {
122-
subject.changeState(newInputs)
123-
}
126+
subject.loopStates();
124127
if(subject.data.outputs) {
125128
subject.changeStateBelow()
126129
}
@@ -250,40 +253,43 @@ class Block extends Entity {
250253

251254
destroy() {
252255
let evaluate = Array.from(category("blocks"));
253-
254256
// Check above
255257
for(let i=0; i<this.data.outputs.length; i++) {
256258
for(let j=0; j<this.data.outputs[i].length; j++) {
257259
let evalElement = evaluate[this.data.outputs[i][j]];
258-
let inputIndex = evalElement.data.inputs.map((x, index) => {
259-
if(x[0] == this.index) {
260-
return index;
261-
}
262-
})
263-
for(let indexItem of inputIndex) {
264-
if(indexItem > -1) {
265-
evalElement.data.inputs[indexItem] = [-1];
260+
if(evalElement) {
261+
let inputIndex = evalElement.data.inputs.map((x, index) => {
262+
if(x[0] == this.index) {
263+
return index;
264+
}
265+
})
266+
for(let indexItem of inputIndex) {
267+
if(indexItem > -1) {
268+
evalElement.data.inputs[indexItem] = [-1];
269+
}
266270
}
267271
}
268272
}
269273
}
270274

271275
// Check below
272276
for(let k=0; k<this.data.inputs.length; k++) {
273-
if(this.data.inputs[k] && this.data.inputs[k][0] != -1) {
274-
let outputs = evaluate[this.data.inputs[k][0]].data.outputs;
275-
let outputIndex = this.data.inputs[k][1]
276-
let secondLevel = outputs[outputIndex].indexOf(this.index);
277-
outputs[outputIndex].splice(secondLevel, 1)
277+
if(this.data.inputs[k]) {
278+
let outputs = evaluate[this.data.inputs[k][0]];
279+
if(outputs) {
280+
let outputIndex = this.data.inputs[k][1]
281+
let secondLevel = outputs.data.outputs[outputIndex].indexOf(this.index);
282+
outputs.data.outputs[outputIndex].splice(secondLevel, 1)
283+
}
278284
}
279285
}
286+
280287
if(selectors.includes(this)) {
281288
let index = selectors.indexOf(this);
282289
selectors.splice(index, 1);
283290
}
284291

285292
this.remove()
286-
287293
// Final Check on all
288294
this.reduceItems(this.index)
289295
}

src/script/entities/button.js

+30-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
class Button extends Entity {
2-
constructor(x, y, width, height, text, colour = "#FFF", border = false, logic = "") {
2+
constructor(x, y, width, height, text, colour = "#FFF", border = false, logic = "", disabled) {
33
super()
44
this.categories = ["button"]
55
this.x = this.defX = x;
@@ -15,14 +15,18 @@ class Button extends Entity {
1515
this.text = text;
1616
this.triggered = false;
1717
this.hovered = false;
18-
}
19-
get z() {
20-
return 11;
18+
this.index = 0;
19+
this.disabled = disabled || (() => false);
20+
this.layer = 11;
2121
}
2222
run() {
23+
let disabled = this.disabled()
2324
this.hovered = false;
2425
let select = Array.from(category("selector"));
26+
let buttons = Array.from(category("button"));
27+
let popUp = Array.from(category("popup"));
2528

29+
this.index = buttons.indexOf(this);
2630
if(holding != -1) return false
2731
if(typeof this.defX == "string") {
2832
this.x = eval(this.defX)
@@ -32,26 +36,37 @@ class Button extends Entity {
3236
}
3337
if(MOUSE_POSITION.x > this.x - this.width / 2 && MOUSE_POSITION.x < this.x + this.width / 2) {
3438
if(MOUSE_POSITION.y > this.y && MOUSE_POSITION.y < (this.y + this.height)) {
35-
if(!select[0].active) {
36-
this.hovered = true;
37-
}
38-
if(MOUSE_DOWN && !this.triggered && !select[0].active) {
39-
this.function();
40-
selectors = [];
41-
this.triggered = true;
39+
if(!popUp[0] || popUps[popUp[0].type].entities.includes(this)) {
40+
if(select[0] && !select[0].active || !select[0]) {
41+
this.hovered = true;
42+
}
4243
}
4344
}
4445
}
45-
if(!MOUSE_DOWN) {
46-
this.triggered = false;
46+
if(MOUSE_DOWN && !this.triggered && this.hovered && !disabled) {
47+
if(clickedButton != -1) return
48+
clickedButton = this.index;
49+
this.function();
50+
selectors = [];
51+
this.triggered = true;
52+
} else {
53+
if(!MOUSE_DOWN){
54+
this.triggered = false;
55+
clickedButton = -1;
56+
}
4757
}
4858
}
4959
draw() {
50-
if(this.hovered) {
60+
let disabled = this.disabled()
61+
if(this.hovered && !disabled) {
62+
console.log(clickedButton)
5163
document.body.style.cursor = "pointer"
64+
ctx.globalAlpha = 0.8;
65+
}
66+
if(disabled) {
5267
ctx.globalAlpha = 0.4;
5368
}
54-
ctx.fillStyle = this.colour;
69+
ctx.fillStyle = (this.colour == "value") ? colourValue: this.colour;
5570
ctx.strokeStyle = this.border;
5671
ctx.lineWidth = 2;
5772
ctx.beginPath();

src/script/entities/default.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ class defaultBlock extends Block {
1515
this.data.outputs.push([]);
1616
if(this.type != "input") {
1717
this.currentValue.push(0)
18-
} else {
19-
this.currentValue.push(1)
2018
}
2119
}
2220
}
21+
if(this.type == "input") {
22+
this.currentValue = [1]
23+
}
2324
if(this.type == "output") {
2425
this.currentValue = [0]
2526
}

0 commit comments

Comments
 (0)