WIP:0.4.3 Multi-Select
This commit is contained in:
parent
fd3cea317f
commit
0eb96aead8
@ -12,6 +12,10 @@ To be decided, but at this moment this code is open source and free to use for n
|
||||
|
||||
## Changelog
|
||||
|
||||
### 0.4.3
|
||||
|
||||
* There is now multi-selection, including movement, deleting, disconnecting, etc.
|
||||
|
||||
### 0.4.2
|
||||
|
||||
* Added Hex keypad with 4 bit output, also has 3 function keys
|
||||
|
@ -80,6 +80,15 @@ class elementContainer {
|
||||
this.ICOutputs = 0;
|
||||
}
|
||||
|
||||
isSelected(element) {
|
||||
if (this.Selected) {
|
||||
for (let a = 0; a < this.Selected.length; a++) {
|
||||
if (this.Selected[a] == element) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
isHigh(element,input) {
|
||||
let isHigh = false;
|
||||
for (let a = 0; a < this.Elements.length; a++) {
|
||||
@ -121,15 +130,30 @@ class elementContainer {
|
||||
}
|
||||
|
||||
DeleteElement(element) {
|
||||
// Can pass object or Designator
|
||||
for (let a = 0; a < this.Elements.length; a++) {
|
||||
if ((this.Elements[a] == element) || (this.Elements[a].Designator == element)) {
|
||||
this.Elements[a].Delete();
|
||||
this.Elements.splice(a,1);
|
||||
return true;
|
||||
// Can pass object or Designator, or array
|
||||
if (Array.isArray(element)) {
|
||||
let returnval = false;
|
||||
for (let a = 0; a < element.length; a++) {
|
||||
for (let b = 0; b < this.Elements.length; b++) {
|
||||
if ((this.Elements[b] == element[a]) || (this.Elements[b].Designator == element[a])) {
|
||||
this.Elements[b].Delete();
|
||||
this.Elements.splice(b, 1);
|
||||
b--;
|
||||
returnval = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnval;
|
||||
} else {
|
||||
for (let a = 0; a < this.Elements.length; a++) {
|
||||
if ((this.Elements[a] == element) || (this.Elements[a].Designator == element)) {
|
||||
this.Elements[a].Delete();
|
||||
this.Elements.splice(a, 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
HasElement(element) {
|
||||
@ -144,8 +168,17 @@ class elementContainer {
|
||||
|
||||
Disconnect(element) {
|
||||
if (!element) return false;
|
||||
for (let a = 0; a < this.Elements.length; a++) {
|
||||
this.Elements[a].Disconnect(element);
|
||||
|
||||
if (Array.isArray(element)) {
|
||||
for (let a = 0; a < this.Elements.length; a++) {
|
||||
for (let b = 0; b < element.length; b++) {
|
||||
this.Elements[a].Disconnect(element[b]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let a = 0; a < this.Elements.length; a++) {
|
||||
this.Elements[a].Disconnect(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,7 +196,7 @@ class elementContainer {
|
||||
if (this.Elements[a] instanceof ICOutput) ICOuts++;
|
||||
if (this.Elements[a].isVisible()) {
|
||||
ctx.save();
|
||||
if (this.Elements[a] == this.Selected) this.Elements[a].drawBorderBox(ctx, this.Elements[a].X - 2, this.Elements[a].Y - 2, this.Elements[a].Width + 4, this.Elements[a].Height + 4, 1, "rgba(100,200,255,0.25)", "rgba(100,200,255,0.25)");
|
||||
if (this.isSelected(this.Elements[a])) this.Elements[a].drawBorderBox(ctx, this.Elements[a].X - 2, this.Elements[a].Y - 2, this.Elements[a].Width + 4, this.Elements[a].Height + 4, 1, "rgba(100,200,255,0.25)", "rgba(100,200,255,0.25)");
|
||||
this.Elements[a].drawElement(this.Elements[a].X, this.Elements[a].Y, ctx);
|
||||
ctx.restore();
|
||||
}
|
||||
@ -171,8 +204,10 @@ class elementContainer {
|
||||
|
||||
this.ICOutputs = ICOuts;
|
||||
if (!this.Selected) {
|
||||
let PropertiesBox = document.getElementById("PropertiesBox");
|
||||
if (PropertiesBox.style.display != "none") PropertiesBox.style.display = "none";
|
||||
if (this.Selected.length == 1) {
|
||||
let PropertiesBox = document.getElementById("PropertiesBox");
|
||||
if (PropertiesBox.style.display != "none") PropertiesBox.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
if (logicEngine.Settings.TopConnections && !logicEngine.Settings.HideConnections) {
|
||||
@ -184,29 +219,37 @@ class elementContainer {
|
||||
|
||||
}
|
||||
|
||||
SelectWithin(x1,y1,x2,y2) {
|
||||
let selectedArray = new Array();
|
||||
for (let a = 0; a < this.Elements.length; a++) {
|
||||
if ((this.Elements[a].X >= x1) && ((this.Elements[a].X + this.Elements[a].Width) <= x2) && (this.Elements[a].Y >= y1) && ((this.Elements[a].Y + this.Elements[a].Height) <= y2)) selectedArray.push(this.Elements[a]);
|
||||
}
|
||||
this.Selected = selectedArray;
|
||||
}
|
||||
|
||||
Select(element) {
|
||||
this.Selected = element;
|
||||
this.Selected = new Array(element);
|
||||
let PropertiesBox = document.getElementById("PropertiesBox");
|
||||
let PropertiesBoxTitle = document.getElementById("PropertiesBoxTitle");
|
||||
let PropertiesBoxContent = document.getElementById("PropertiesBoxContent");
|
||||
PropertiesBoxTitle.innerText = this.Selected.Designator + " Properties";
|
||||
PropertiesBoxTitle.innerText = this.Selected[0].Designator + " Properties";
|
||||
let contentString = "<table id='propertiesTable'>";
|
||||
for (let a = 0; a < this.Selected.Properties.length;a++) {
|
||||
contentString += "<tr><td>" + this.Selected.Properties[a].Name + "</td><td>";
|
||||
switch (this.Selected.Properties[a].Type) {
|
||||
for (let a = 0; a < this.Selected[0].Properties.length;a++) {
|
||||
contentString += "<tr><td>" + this.Selected[0].Properties[a].Name + "</td><td>";
|
||||
switch (this.Selected[0].Properties[a].Type) {
|
||||
case "int":
|
||||
contentString += "<input type='number' id='prop_" + this.Selected.Properties[a].Name + "' min='" + this.Selected.Properties[a].Minimium + "' max='" + this.Selected.Properties[a].Maximium + "' value='" + this.Selected.Properties[a].CurrentValue + "' onchange='logicEngine.PropertyChange(" + String.fromCharCode(34) + this.Selected.Properties[a].Name + String.fromCharCode(34) +");'>";
|
||||
contentString += "<input type='number' id='prop_" + this.Selected[0].Properties[a].Name + "' min='" + this.Selected[0].Properties[a].Minimium + "' max='" + this.Selected[0].Properties[a].Maximium + "' value='" + this.Selected[0].Properties[a].CurrentValue + "' onchange='logicEngine.PropertyChange(" + String.fromCharCode(34) + this.Selected[0].Properties[a].Name + String.fromCharCode(34) +");'>";
|
||||
break;
|
||||
case "string":
|
||||
contentString += '<input type="text" id="prop_' + this.Selected.Properties[a].Name + '" minlength="' + this.Selected.Properties[a].Minimium + '" maxlength="' + this.Selected.Properties[a].Maximium + '" value="' + this.Selected.Properties[a].CurrentValue + '" onchange="logicEngine.PropertyChange(' + String.fromCharCode(39) + this.Selected.Properties[a].Name + String.fromCharCode(39) + ');">';
|
||||
contentString += '<input type="text" id="prop_' + this.Selected[0].Properties[a].Name + '" minlength="' + this.Selected[0].Properties[a].Minimium + '" maxlength="' + this.Selected[0].Properties[a].Maximium + '" value="' + this.Selected[0].Properties[a].CurrentValue + '" onchange="logicEngine.PropertyChange(' + String.fromCharCode(39) + this.Selected[0].Properties[a].Name + String.fromCharCode(39) + ');">';
|
||||
break;
|
||||
case "color":
|
||||
contentString += '<input type="color" id="prop_' + this.Selected.Properties[a].Name + '" value="' + this.Selected.Properties[a].CurrentValue + '" onchange="logicEngine.PropertyChange(' + String.fromCharCode(39) + this.Selected.Properties[a].Name + String.fromCharCode(39) + ');">';
|
||||
contentString += '<input type="color" id="prop_' + this.Selected[0].Properties[a].Name + '" value="' + this.Selected[0].Properties[a].CurrentValue + '" onchange="logicEngine.PropertyChange(' + String.fromCharCode(39) + this.Selected[0].Properties[a].Name + String.fromCharCode(39) + ');">';
|
||||
break;
|
||||
case "list":
|
||||
contentString += '<select id="prop_' + this.Selected.Properties[a].Name + '" onchange="logicEngine.PropertyChange(' + String.fromCharCode(39) + this.Selected.Properties[a].Name + String.fromCharCode(39) + ');">';
|
||||
for (let b = 0; b < this.Selected.Properties[a].Values.length; b++) {
|
||||
contentString += '<option value="' + this.Selected.Properties[a].Values[b].Value + '" '+ ((this.Selected.Properties[a].Values[b].Value == this.Selected.Properties[a].CurrentValue) ? ' selected' : '') + '>' + this.Selected.Properties[a].Values[b].String + '</option>';
|
||||
contentString += '<select id="prop_' + this.Selected[0].Properties[a].Name + '" onchange="logicEngine.PropertyChange(' + String.fromCharCode(39) + this.Selected[0].Properties[a].Name + String.fromCharCode(39) + ');">';
|
||||
for (let b = 0; b < this.Selected[0].Properties[a].Values.length; b++) {
|
||||
contentString += '<option value="' + this.Selected[0].Properties[a].Values[b].Value + '" '+ ((this.Selected[0].Properties[a].Values[b].Value == this.Selected[0].Properties[a].CurrentValue) ? ' selected' : '') + '>' + this.Selected[0].Properties[a].Values[b].String + '</option>';
|
||||
}
|
||||
contentString += '</select>';
|
||||
break;
|
||||
|
@ -75,12 +75,17 @@ class LogicEngine {
|
||||
let element = this.ActiveContainer.checkMouseBounds(mousePos);
|
||||
if (element) {
|
||||
this.MouseDown = true;
|
||||
this.ActiveContainer.Select(element);
|
||||
this.MovingElement = element;
|
||||
this.MovingElementStartX = element.X;
|
||||
this.MovingElementStartY = element.Y;
|
||||
this.MovingElementMouseStartX = mousePos.x;
|
||||
this.MovingElementMouseStartY = mousePos.y;
|
||||
if (this.ActiveContainer.Selected.length <= 1) this.ActiveContainer.Select(element);
|
||||
this.MovingElement = new Array(this.ActiveContainer.Selected.length);
|
||||
|
||||
for (let a = 0; a < this.ActiveContainer.Selected.length; a++) {
|
||||
this.MovingElement[a] = {
|
||||
StartX: this.ActiveContainer.Selected[a].X,
|
||||
StartY: this.ActiveContainer.Selected[a].Y
|
||||
};
|
||||
this.MovingElementMouseStartX = mousePos.x;
|
||||
this.MovingElementMouseStartY = mousePos.y;
|
||||
}
|
||||
element.MouseDown(mousePos);
|
||||
} else {
|
||||
this.MouseDown = true;
|
||||
@ -90,6 +95,15 @@ class LogicEngine {
|
||||
this.Panning.StartOffsetY = this.Panning.OffsetY;
|
||||
this.Panning.StartX = mousePos.x;
|
||||
this.Panning.StartY = mousePos.y;
|
||||
} else {
|
||||
|
||||
let cmPos = this.getCanvasMousePos(mousePos);
|
||||
this.MultiSelectStart.InProgress = true;
|
||||
this.MultiSelectStart.x = cmPos.x;
|
||||
this.MultiSelectStart.y = cmPos.y;
|
||||
this.ActiveContainer.Selected = false;
|
||||
let PropertiesBox = document.getElementById("PropertiesBox");
|
||||
PropertiesBox.style.display = "none";
|
||||
}
|
||||
}
|
||||
if (this.ActiveContainer.Selected) {
|
||||
@ -102,18 +116,35 @@ class LogicEngine {
|
||||
|
||||
Mouse_Up(evt) {
|
||||
let mousePos = getMousePos(this.Canvas, evt);
|
||||
if (this.MovingElement) this.MovingElement.MouseUp(mousePos);
|
||||
if (this.MovingElement) {
|
||||
let element = this.ActiveContainer.checkMouseBounds(mousePos);
|
||||
if (element) element.MouseUp(mousePos);
|
||||
}
|
||||
|
||||
if (this.MovingElement && (this.MovingElement.X == this.MovingElementStartX) && (this.MovingElement.Y == this.MovingElementStartY)) {
|
||||
if ((performance.now() - this.MouseDownTime) < 3000) {
|
||||
// Presume this was a click
|
||||
this.MovingElement.MouseClick(mousePos);
|
||||
let element = this.ActiveContainer.checkMouseBounds(mousePos);
|
||||
if (element) element.MouseClick(mousePos);
|
||||
}
|
||||
//console.log("Mouse Up");
|
||||
}
|
||||
if (!this.MovingElement && evt.which === 1) this.ActiveContainer.Selected = false;
|
||||
if (!this.MovingElement && evt.which === 1) {
|
||||
this.ActiveContainer.Selected = false;
|
||||
let PropertiesBox = document.getElementById("PropertiesBox");
|
||||
PropertiesBox.style.display = "none";
|
||||
}
|
||||
|
||||
this.MovingElement = false;
|
||||
this.MouseDown = false;
|
||||
|
||||
if (this.MultiSelectStart.InProgress) {
|
||||
this.MultiSelectStart.InProgress = false;
|
||||
let cmStartPos = {x: this.MultiSelectStart.x, y: this.MultiSelectStart.y};
|
||||
let cmEndPos = this.getCanvasMousePos(mousePos);
|
||||
this.ActiveContainer.SelectWithin(cmStartPos.x,cmStartPos.y,cmEndPos.x,cmEndPos.y);
|
||||
}
|
||||
|
||||
if (this.ActiveContainer.Selected) {
|
||||
disableSelectedRCMs(false);
|
||||
} else {
|
||||
@ -128,18 +159,26 @@ class LogicEngine {
|
||||
if(this.MouseDown) {
|
||||
//console.log('Mouse at position: ' + mousePos.x + ',' + mousePos.y);
|
||||
if (this.MovingElement) {
|
||||
|
||||
if ((performance.now() - this.MouseDownTime) > 100) {
|
||||
let xOffset = mousePos.x - this.MovingElementMouseStartX;
|
||||
let yOffset = mousePos.y - this.MovingElementMouseStartY;
|
||||
let diffxOffset = this.MovingElementMouseStartX - this.MovingElementStartX;
|
||||
let diffyOffset = this.MovingElementMouseStartY - this.MovingElementStartY;
|
||||
let actualPosX = (this.MovingElementMouseStartX + xOffset) - diffxOffset;
|
||||
let actualPosY = (this.MovingElementMouseStartY + yOffset) - diffyOffset;
|
||||
if (!this.ControlPressed && this.Settings.SnapGrid) actualPosX = Math.round(actualPosX/this.Settings.GridSize)*this.Settings.GridSize;
|
||||
if (!this.ControlPressed && this.Settings.SnapGrid) actualPosY = Math.round(actualPosY/this.Settings.GridSize)*this.Settings.GridSize;
|
||||
this.MovingElement.X = actualPosX;
|
||||
this.MovingElement.Y = actualPosY;
|
||||
|
||||
for (let a = 0; a < this.ActiveContainer.Selected.length; a++) {
|
||||
let diffxOffset = this.MovingElementMouseStartX - this.MovingElement[a].StartX;
|
||||
let diffyOffset = this.MovingElementMouseStartY - this.MovingElement[a].StartY;
|
||||
let actualPosX = (this.MovingElementMouseStartX + xOffset) - diffxOffset;
|
||||
let actualPosY = (this.MovingElementMouseStartY + yOffset) - diffyOffset;
|
||||
|
||||
if (!this.ControlPressed && this.Settings.SnapGrid) actualPosX = Math.round(actualPosX / this.Settings.GridSize) * this.Settings.GridSize;
|
||||
if (!this.ControlPressed && this.Settings.SnapGrid) actualPosY = Math.round(actualPosY / this.Settings.GridSize) * this.Settings.GridSize;
|
||||
|
||||
this.ActiveContainer.Selected[a].X = actualPosX;
|
||||
this.ActiveContainer.Selected[a].Y = actualPosY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
if (this.ControlPressed) {
|
||||
let distX = mousePos.x - this.Panning.StartX;
|
||||
@ -181,6 +220,8 @@ class LogicEngine {
|
||||
if (this.ActiveContainer.Selected) {
|
||||
this.ActiveContainer.DeleteElement(this.ActiveContainer.Selected);
|
||||
this.ActiveContainer.Selected = false;
|
||||
let PropertiesBox = document.getElementById("PropertiesBox");
|
||||
PropertiesBox.style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -200,8 +241,6 @@ class LogicEngine {
|
||||
this.MouseDownTime = 0;
|
||||
this.MovingElementContainer = false;
|
||||
this.MovingElement = false;
|
||||
this.MovingElementStartX = 0;
|
||||
this.MovingElementStartY = 0;
|
||||
this.MovingElementMouseStartX = 0;
|
||||
this.MovingElementMouseStartY = 0;
|
||||
this.ActiveContainer = new elementContainer();
|
||||
@ -212,20 +251,26 @@ class LogicEngine {
|
||||
this.Canvas.setAttribute('tabindex','0');
|
||||
this.ControlPressed = false;
|
||||
this.Panning = {OffsetX: 0, OffsetY: 0,StartOffsetX: 0, StartOffsetY: 0, StartX: 0, StartY: 0};
|
||||
this.MultiSelectStart = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
InProgress: false
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
Link(input = 0) {
|
||||
if (this.ActiveLink) {
|
||||
if (this.ActiveContainer.Selected && (this.ActiveContainer.Selected != this.ActiveLink)) {
|
||||
this.ActiveLink.addConnection(this.ActiveContainer,this.ActiveContainer.Selected,input,this.ActiveLink.OutputLink.Output);
|
||||
this.ActiveLink.addConnection(this.ActiveContainer,this.ActiveContainer.Selected[0],input,this.ActiveLink.OutputLink.Output);
|
||||
this.ActiveLink = false;
|
||||
} else {
|
||||
this.ActiveLink = false;
|
||||
}
|
||||
} else {
|
||||
if (this.ActiveContainer.Selected) {
|
||||
this.ActiveLink = this.ActiveContainer.Selected;
|
||||
if (this.ActiveContainer.Selected.length == 1) {
|
||||
this.ActiveLink = this.ActiveContainer.Selected[0];
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,6 +287,12 @@ class LogicEngine {
|
||||
}
|
||||
let startLoop = performance.now();
|
||||
this.Ctx.clearRect(0- this.Panning.OffsetX,0- this.Panning.OffsetY,this.Canvas.width,this.Canvas.height);
|
||||
let ct = new CanvasTools();
|
||||
|
||||
if (this.MultiSelectStart.InProgress) {
|
||||
let cmPos = this.getCanvasMousePos(this.Mouse);
|
||||
ct.drawBorderBox(this.Ctx,this.MultiSelectStart.x,this.MultiSelectStart.y,cmPos.x - this.MultiSelectStart.x,cmPos.y - this.MultiSelectStart.y,0,"rgba(100,200,255,0.25)","rgba(100,200,255,0.25)");
|
||||
}
|
||||
|
||||
this.ActiveContainer.DrawAll(this.Ctx,this.Settings);
|
||||
let tfm_CreateIC = document.getElementById("tfm_CreateIC");
|
||||
@ -275,7 +326,6 @@ class LogicEngine {
|
||||
this.Ctx.stroke();
|
||||
this.Ctx.restore();
|
||||
}
|
||||
let ct = new CanvasTools();
|
||||
let FPSOffset = 5 - this.Panning.OffsetX;
|
||||
if (this.Settings.ShowFPS) {
|
||||
ct.drawText(this.Ctx, FPSOffset, 15 - this.Panning.OffsetY, "FPS: " + this.FPS, "12px console", "#00ff00");
|
||||
|
@ -2,7 +2,7 @@
|
||||
MatCat BrowserLogic Simulator
|
||||
*/
|
||||
|
||||
let Version = "0.4.2";
|
||||
let Version = "0.4.3";
|
||||
let spanVersion = document.getElementById("version");
|
||||
spanVersion.innerText = Version;
|
||||
// get the canvas and get the engine object going
|
||||
@ -145,7 +145,9 @@ tfm_Delete.addEventListener('click', function(evt) {
|
||||
|
||||
let rcm_Disconect = document.getElementById("rcm_Disconnect");
|
||||
rcm_Disconect.addEventListener('click', function(evt) {
|
||||
logicEngine.ActiveContainer.Selected.Disconnect();
|
||||
for (let a = 0; a < logicEngine.ActiveContainer.Selected.length;a++) {
|
||||
logicEngine.ActiveContainer.Selected[a].Disconnect();
|
||||
}
|
||||
logicEngine.ActiveContainer.Disconnect(logicEngine.ActiveContainer.Selected);
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user