EduNetworkBuilder/Web/ui.js

919 lines
30 KiB
JavaScript

//Make sure canvasses are in the correct positionG
var maincanvas= document.querySelector("MainCanvas");
var MainCanvas = document.getElementById("MainCanvas");
var MainCanvas_ctx = MainCanvas.getContext("2d");
var maincanvasBackground="lightgrey";
var mouseIsDown=false;
var mouseDownLocation;
var mouseDidMovement=false;
var imageSize=40;
var small_button_size = 25;
var uiDeviceInfoLevel = 1; //What do we display when we look at the network
var uiActions = [];//a list of things on the screen we can click on or process.
var ui_highlightRect = null;
var ui_selectRect = null;
var ui_HadHighlight = false;
var ui_status_height = 25;
var ui_StatusText = "";
var ui_HighlightArray = [];
var translator = new Language("en");
//The user interface mode. 0=network, 1=network information, 2=puzzle-selection menu
var uiMode=1;
const imageCollection = loadImages(
["ArrowUp", "ArrowDown", "animations",
"burnmark", "cellphone", "circle",
"copier", "firewall", "fluorescent",
"hub", "ip_phone", "laptop",
"link", "microwave", "pc", "printer",
"router", "select", "server",
"shapes", "square", "switch",
"tablet", "tree", "vidimage",
"wap", "wbridge", "wrepeater",
"wrouter", "x", "info", "menu",
"eye", "queryuser", "thumb",
],
["img/ArrowUp.png", "img/ArrowDown.png", "img/Animations.png",
"img/BurnMark.png", "img/cellphone.png", "img/Circle.png",
"img/Copier.png", "img/firewall.png", "img/fluorescent.png",
"img/Hub.png", "img/ip_phone.png", "img/Laptop.png",
"img/link.png", "img/microwave.png", "img/PC.png",
"img/Printer.png", "img/Router.png", "img/select.png",
"img/Server.png", "img/Shapes.png", "img/Square.png",
"img/Switch.png", "img/tablet.png", "img/tree.png",
"img/VidImage.png", "img/WAP.png", "img/WBridge.png",
"img/WRepeater.png", "img/WRouter.png", "img/X.png",
"img/info.png", "img/menu.png", "img/eye.png",
"img/queryuser.png", "img/thumb.png",
],
InitializeGameMenu // this is called when all images have loaded.
);
var menuItemSize=50;
function loadImages(names, files, onAllLoaded) {
var i = 0, numLoading = names.length;
const onload = () => --numLoading === 0 && onAllLoaded();
const images = {};
while (i < names.length) {
const img = images[names[i]] = new Image;
img.src = files[i++];
img.onload = onload;
}
return images;
}
function imageFromName(name)
{
return imageCollection[name];
}
function InitializeGameMenu()
{
console.log("Initializing");
MainCanvas.addEventListener("touchstart", handleTouchStart);
MainCanvas.addEventListener("touchend", handleTouchEnd);
MainCanvas.addEventListener("touchcancel", handleTouchCancel);
MainCanvas.addEventListener("touchmove", handleTouchMove);
MainCanvas.addEventListener('mousedown',handleMouseDown);
MainCanvas.addEventListener('mouseup',handleMouseUp);
MainCanvas.addEventListener('mousemove',handleMouseMove);
//MainCanvas_ctx.drawImage(imageCollection['router'],100,100,50,50);
//MainCanvas_ctx.drawImage(imageCollection['firewall'],150,150,50,50);
InitializeSelectMenu();
//It should be printed
PrintScreen();
}
//Print the screen. Figure out what needs to be printed based on the mode
function PrintScreen(WhatPassedIn=-1)
{
//allow us to override what is printed
var what=uiMode;
if(WhatPassedIn >=0) what=WhatPassedIn;
//Clear out any old ActionStructs. They will get filled in as we print the screen.
clearActionStructs();
//console.log("PrintingScreen for mode: " + what);
var rect;
if(what == 0)
{
//The network drawing mode. Print the network
//Clear the old screen
MainCanvas_ctx.fillStyle = maincanvasBackground;
MainCanvas_ctx.fillRect(0, 0, MainCanvas.width, MainCanvas.height);
//Check for device highlights
checkDevicesForIssues();
//print highlights. If we have mouseover highlights, note that.
if (printHighlights("mouseover") > 0) ui_HadHighlight = true;
else ui_HadHighlight = false;
//Draw the puzzle-select button
//Put the X there so we can click on it
rect = makeRectangle(MainCanvas.width - small_button_size, 0, small_button_size, small_button_size);
MainCanvas_ctx.drawImage(imageFromName("menu"),rect.sx,rect.sy,rect.deltax,rect.deltay);
registerActionStruct("square", rect, null, ui_PuzzleChoiceMenuLeftClick, null, generic_mouseoverHighlight);
//Draw the info button
rect = makeRectangle(MainCanvas.width - small_button_size, small_button_size, small_button_size, small_button_size);
MainCanvas_ctx.drawImage(imageFromName("info"), rect.sx, rect.sy, rect.deltax, rect.deltay);
registerActionStruct("square", rect, null, ui_InfoLeftClick, null, generic_mouseoverHighlight);
//Draw the eye button
rect = makeRectangle(MainCanvas.width - small_button_size, small_button_size * 2, small_button_size, small_button_size);
MainCanvas_ctx.drawImage(imageFromName("eye"), rect.sx, rect.sy, rect.deltax, rect.deltay);
registerActionStruct("square", rect, null, ui_eyeLeftClick, null, generic_mouseoverHighlight);
//Draw the help-level select button
rect = makeRectangle(MainCanvas.width - small_button_size, small_button_size * 3, small_button_size, small_button_size);
//Put any coloring behind the query-user image
var tmp_queryhighlight = null;
if (ui_helplevel == 0) tmp_queryhighlight = returnHighlightShape("square", rect, "red", "none", 0.3);
if (ui_helplevel == 1) tmp_queryhighlight = returnHighlightShape("square", rect, "orange", "none", 0.3);
if (ui_helplevel == 2) tmp_queryhighlight = returnHighlightShape("square", rect, "yellow", "none", 0.3);
if (ui_helplevel == 3) tmp_queryhighlight = returnHighlightShape("square", rect, "green", "none", 0.3);
if (tmp_queryhighlight == null) { }
else drawshape(tmp_queryhighlight);
MainCanvas_ctx.drawImage(imageFromName("queryuser"), rect.sx, rect.sy, rect.deltax, rect.deltay);
registerActionStruct("square", rect, null, ui_queryuserLeftClick, null, generic_mouseoverHighlight);
//Draw simple lines to show boundaries
//Select menu separation
MainCanvas_ctx.lineWidth = 2;
MainCanvas_ctx.strokeStyle = "white";
MainCanvas_ctx.beginPath();
MainCanvas_ctx.moveTo(menuItemSize, 0); //top side
MainCanvas_ctx.lineTo(menuItemSize, MainCanvas.height); //Bottom
MainCanvas_ctx.stroke();
//Right-side menu separator
MainCanvas_ctx.beginPath();
MainCanvas_ctx.moveTo(MainCanvas.width - small_button_size, 0); //top side
MainCanvas_ctx.lineTo(MainCanvas.width - small_button_size, MainCanvas.height - ui_status_height); //Bottom
MainCanvas_ctx.stroke();
//Status Bar separator
MainCanvas_ctx.beginPath();
MainCanvas_ctx.moveTo(menuItemSize, MainCanvas.height - ui_status_height); //top side
MainCanvas_ctx.lineTo(MainCanvas.width, MainCanvas.height - ui_status_height); //Bottom
MainCanvas_ctx.stroke();
var statustext = puzzle.name + ": " + ui_StatusText;
printLeftJustifiedText(MainCanvas_ctx, statustext, menuItemSize + 5, (MainCanvas.height - ui_status_height) + 7);
MainCanvas_ctx.strokeStyle = "black";
if (ui_selectRect == null) { }
else {
//console.log("We have something selected.");
var tmp_select = returnHighlightShape("selectbox", ui_selectRect, "green", "none", 0.8);
drawshape(tmp_select);
}
drawSelectMenu();
PrintAllNetworkLinks();
PrintAllNetworkDevices();
}
else if(what == 1) //PuzzleDescription/Info
{
//Display the text about the puzzle
console.log("Using language: " + ui_language);
textMenuPrint(eval('puzzle.' + ui_language + '_message'));
}
else if(what == 2) //PuzzleSelect
{
//TextMenuSelection
PrintPuzzleSelectMenu(0);
}
}
function handleTouchStart(evt)
{
handleMouseDown(copyLocation(evt));
}
function handleTouchEnd(evt)
{
handleMouseUp(copyLocation(evt));
}
function handleTouchCancel(evt)
{
evt.preventDefault();
console.log("canceling touch");
}
function handleTouchMove(evt)
{
//evt.preventDefault();
if(evt.touches.length > 0)
{
handleMouseMove(copyLocation(evt.touches[0]));
} else{
//console.log("not enough touches");
}
//console.log("moving touch");
}
function handleMouseDown(evt)
{
mouseDownLocation = copyLocation(evt);
mouseIsDown=true;
//console.log("mousedown");
if(uiMode==0) SelectMenu_handleMouseDown(mouseDownLocation);
}
function CheckForActions(actionPoint, action) {
if (uiActions.length >= 0) {
var checkit = false;
var inside = false;
for (var index = 0; index < uiActions.length; index++) {
checkit = true;
if (action == "leftclick" && uiActions[index].funcLeftClick == null) checkit = false;
if (action == "rightclick" && uiActions[index].funcRightClick == null) checkit = false;
if (action == "mouseover" && uiActions[index].funcMouseover == null) checkit = false;
checklocation = uiActions[index];
var point = newPointFromPair(actionPoint.pageX - checklocation.shapePoints.offsetx, actionPoint.pageY - checklocation.shapePoints.offsety);
if (checkit) {
//See if the click is inside the shape
if (checklocation.shapeText == "square") {
if (pointInRect(point, checklocation.shapePoints))
inside = true;
}
if (checklocation.shapeText == "line") {
if (pointInRect(point, checklocation.shapePoints)) {
//console.log("inside line square");
//We are inside the box. Now determine if we are on the line...
var d1 = distance(checklocation.shapePoints.sx, checklocation.shapePoints.sy, actionPoint.pageX, actionPoint.pageY);
d1 += distance(checklocation.shapePoints.dx, checklocation.shapePoints.dy, actionPoint.pageX, actionPoint.pageY);
var d2 = distance(checklocation.shapePoints.sx, checklocation.shapePoints.sy, checklocation.shapePoints.dx, checklocation.shapePoints.dy);
if (Math.abs(d1 - d2) < 3) {
inside = true;
//console.log("on a line!");
}
}
}
}
if (inside) {
//console.log("Is inside");
switch (action) {
case "leftclick":
if (checklocation.funcLeftClick == null) { }
else {
checklocation.funcLeftClick(actionPoint, checklocation);
//console.log("Successfully did a left-click UI action");
return true;
}
break;
case "mouseover":
if (checklocation.funcMouseover == null) { }
else {
checklocation.funcMouseover(actionPoint, checklocation);
//console.log("Successfully did a UI action");
return true;
}
break;
}
}
}
}
return false;
}
function pointInRect(point, rectangle) {
if (point.x >= Math.min(rectangle.sx,rectangle.dx)) {
if (point.x <= Math.max(rectangle.sx, rectangle.dx)) {
if (point.y >= Math.min(rectangle.sy, rectangle.dy)) {
if (point.y <= Math.max(rectangle.sy, rectangle.dy)) {
return true;
}
}
}
}
return false;
}
//return the distance between two points
function distance(x1, y1, x2, y2) {
return Math.hypot(x2 - x1, y2 - y1);
}
function handleMouseUp(evt)
{
//evt.preventDefault();
mouseIsDown = false;
//See if we have a mouse click
let deltaX = Math.abs(evt.pageX - mouseDownLocation.pageX);
let deltaY = Math.abs(evt.pageY - mouseDownLocation.pageY);
//console.log("delta " + deltaX + "," + deltaY);
if(deltaY < 3 && deltaX <3)
{
//We did not move much. Assume click
if(evt.pageX <= menuItemSize && !mouseDidMovement)
{
if(uiMode==0) SelectMenu_handleMouseUp(evt);
//We are in the item select menu.
}
if(!mouseDidMovement)
{ //If we are not dragging, it is a click
var myevt = copyLocation(evt);
var needsrefresh = true;;
if (ui_selectRect == null) needsrefresh = false;
ui_selectRect = null; //remove any previous selected marker
//console.log("evt:" + JSON.stringify(myevt));
if (CheckForActions(myevt, "leftclick")) return; //If we did this, do not do anything else.
if(uiMode==1) TextWindow_handleMouseUp(evt);
else if (uiMode == 2) TextWindow_handleMouseUp(evt);
if (needsrefresh) {
if (ui_selectRect == null) setStatus(""); //we clicked on nothing
PrintScreen();
}
}
}
mouseDidMovement=false; //reset it after we raise the button
}
function ui_PuzzleChoiceMenuLeftClick(evt) {
//We clicked on the puzzle-select menu
console.log("PuzzleSelect pressed in action");
uiMode = 2;
PrintScreen();
}
function ui_eyeLeftClick(evt) {
console.log("Selected 'eye' button in action");
//It is the eye button
uiDeviceInfoLevel++;
if (uiDeviceInfoLevel > 3) uiDeviceInfoLevel = 0;
PrintScreen();
}
function ui_queryuserLeftClick(evt) {
console.log("Selected 'queryuser' button in action");
//It is the eye button
ui_helplevel++;
if (ui_helplevel > 3) ui_helplevel = 0;
if (ui_helplevel == 0) setStatus("There is a disturbance in the force. Guessing...");
if (ui_helplevel == 1) setStatus("Service check detected a problem.");
if (ui_helplevel == 2) setStatus("Someone submitted a trouble ticket.");
if (ui_helplevel == 3) setStatus("Interviewed users for detailed info.");
PrintScreen();
}
function ui_InfoLeftClick(evt) {
console.log("Selected info button in action");
//It is the info button
uiMode = 1;
PrintScreen();
}
function handleMouseMove(evt)
{
//evt.preventDefault();
if(mouseIsDown)
{
let deltaX = evt.pageX - mouseDownLocation.pageX;
let deltaY = evt.pageY - mouseDownLocation.pageY;
if(isNaN(deltaY)) deltaY=0;
if(isNaN(deltaX)) deltaX=0;
//we are dragging
//console.log('mousemove ' + evt.pageX + " " + evt.pageY + " delta " + deltaY );
if(uiMode == 0)
{
SelectMenu_handleMouseMove(evt);
}
mouseDidMovement=true;
}
else //Mouse is not down. Not dragging
{
var needrefresh = false;
var oldRect = structuredClone(findHighlightsNamed("mouseover"));
removeHighlightsNamed("mouseover");
if (!CheckForActions(evt, "mouseover")) {
//We did not find anything
if (oldRect == null) {
}
else {
//We used to have a highlight, but it was removed
needrefresh = true;
}
if (ui_HadHighlight) { needrefresh = true; }
if (needrefresh) {
PrintScreen();
}
}
if(uiMode==2)
{
textMenu_HandleMouseMove(evt);
}
}
return;
}
function copyLocation({ pageX, pageY }) {
return { pageX, pageY };
}
function PrintNetworkLink(linkToPrint)
{
//We should have passed in a working link, make sure it exists
if(linkToPrint !== null)
{
if(linkToPrint.SrcNic !== null && linkToPrint.DestNic !== null)
{
//console.log("printing link from " + linkToPrint.SrcNic.hostname);
sdevice = deviceFromID(linkToPrint.SrcNic.hostid);
ddevice = deviceFromID(linkToPrint.DstNic.hostid);
if(sdevice !== null && ddevice !== null)
{
//We have an existing link with two devices. Find the device locations and print
var spoint = convertXYPointToActual(newPointFromString(sdevice.location));
var dpoint = convertXYPointToActual(newPointFromString(ddevice.location));
//Make an actionstruct
var actionLine = makeLine(spoint.x, spoint.y, dpoint.x, dpoint.y);
registerActionStruct("line", actionLine, linkToPrint, null, null, generic_mouseoverHighlight);
var old
//Now we draw a line between them
MainCanvas_ctx.beginPath();
MainCanvas_ctx.moveTo(spoint.x,spoint.y);
MainCanvas_ctx.lineTo(dpoint.x,dpoint.y);
MainCanvas_ctx.stroke();
}
}
}
}
function PrintAllNetworkLinks()
{
if (puzzle == null) return; //If the puzzle has not been set, exit
let index=0;
if(puzzle.link !== null && typeof(puzzle.link) === "object")
{
while (index < puzzle.link.length) {
PrintNetworkLink(puzzle.link[index]);
index++;
}
}
}
function PrintNetworkDevice(ToPrint)
{
//We should have passed in a working device, make sure it exists
if(ToPrint !== null)
{
var rect = deviceRectangle(ToPrint);
var actionrect = makeRectangle(rect.spoint.x, rect.spoint.y, rect.width, rect.height);
var dname = ToPrint.mytype;
if(dname=="net_switch") dname="switch";
if(dname=="net_hub") dname="hub";
//console.log("printing device " + dname);
if (deviceHasProblem(ToPrint)) {
var thshape = returnHighlightShape("square", actionrect, "red", "problem", 0.2);
drawshape(thshape);
}
MainCanvas_ctx.drawImage(imageFromName(dname), rect.spoint.x, rect.spoint.y, rect.width, rect.height);
registerActionStruct("square", actionrect, ToPrint, device_clickOn, null, generic_mouseoverHighlight);
//Now, we see if we need to print the name, or a list of IPs..
var xpoint = rect.center.x;
var ystart = rect.epoint.y; //the bottom-most Y point
var gap = 3;
var delta;
var ipaddresses = ipsFromDevice(ToPrint);
//console.log("addresses: " + JSON.stringify(ipaddresses));
switch (uiDeviceInfoLevel) {
case 0:
//Do not print anything
break;
case 1:
//Print the name
printCenteredText(MainCanvas_ctx, ToPrint.hostname, xpoint, ystart);
break;
case 2:
case 3:
//console.log("printing device " + ToPrint.hostname);
//Print both the name and the IP addresses
if (uiDeviceInfoLevel == 2) {
delta = printCenteredText(MainCanvas_ctx, ToPrint.hostname, xpoint, ystart) + gap;
ystart += delta / 2;
}
//print the ip addresses
for (var x = 0; x < ipaddresses.length; x++) {
//Print the IP address if the type is correct.
//console.log(JSON.stringify(ipaddresses[x]));
switch (ipaddresses[x].nictype) {
case "eth":
case "management_interface":
//console.log("Found a " + ipaddresses[x].nictype)
let mystring = ipaddresses[x].cidrip;
delta = printCenteredText(MainCanvas_ctx, mystring, xpoint, ystart);
ystart += (delta / 2);
break;
}
}
break;
}
}
}
function checkDevicesForIssues()
{
return; //Doing it a different way
if (puzzle == null) return; //If the puzzle has not been set, exit
removeHighlightsNamed("problem");
//console.log("Looking for problems in devices." + puzzle.device.length);
let index = 0;
while (index < puzzle.device.length) {
if (deviceHasProblem(puzzle.device[index])) {
console.log("Found a problem. Registering it...");
var actionrect = deviceRectangle(puzzle.device[index]);
//If the help level is bigger than 0 (guessing), show which devices have problems
if (ui_helplevel > 0) {
var answer = registerHighlightShape("square", actionrect, "red", "problem", 0.2);
console.log("registered it." + JSON.stringify(answer));
}
}
index++;
}
}
function PrintAllNetworkDevices()
{
if (puzzle == null) return; //If the puzzle has not been set, exit
let index = 0;
while (index < puzzle.device.length) {
PrintNetworkDevice(puzzle.device[index]);
index++;
}
}
//print centered text. We use y as the top-most y position. But we center around the x position
function printCenteredText(canvas_context, text, centerx, top_y, font = "15px serif", textcolor="black") {
var metrics = canvas_context.measureText(text);
var yHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent + tmTextYGap;
var xWidth = metrics.width;
var oldfill = canvas_context.fillStyle;
var oldstroke = canvas_context.strokeStyle;
canvas_context.font = font;
canvas_context.fillStyle = textcolor;
canvas_context.strokeStyle = textcolor;
canvas_context.fillText(text, centerx - (xWidth / 2), top_y + (yHeight / 3));
//reset stuff when done
canvas_context.fillStyle = oldfill;
canvas_context.strokeStyle = oldstroke;
return yHeight; //report back how much space we used. Just in case they want it.
}
//print text. We use y as the top-most y position.
function printLeftJustifiedText(canvas_context, text, LeftX, top_y, font = "15px serif", textcolor = "black") {
var metrics = canvas_context.measureText(text);
var yHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent + tmTextYGap;
var xWidth = metrics.width;
var oldfill = canvas_context.fillStyle;
var oldstroke = canvas_context.strokeStyle;
canvas_context.font = font;
canvas_context.fillStyle = textcolor;
canvas_context.strokeStyle = textcolor;
canvas_context.fillText(text, LeftX, top_y + (yHeight / 3));
//reset stuff when done
canvas_context.fillStyle = oldfill;
canvas_context.strokeStyle = oldstroke;
return yHeight; //report back how much space we used. Just in case they want it.
}
function convertXYPointToActual(point)
{
//We have an x and y coordinate which needs to be converted to the canvas size
var deltax = (MainCanvas.width - menuItemSize) / puzzle.width;
var deltay = MainCanvas.height / puzzle.height;
return newPointFromPair((point.x * deltax) + menuItemSize, point.y * deltay);
}
function convertXYpairToActual(x,y)
{
return convertXYPointToActual(newPointFromPair(x,y));
}
function newPointFromPair(x,y)
{
var point = {
'x' : Math.floor(x),
'y' : Math.floor(y)
}
return point;
}
function newPointFromString(pointasstring)
{
if(typeof(pointasstring) == "string")
{
var tarray=pointasstring.split(",");
return newPointFromPair(Number(tarray[0]),Number(tarray[1]));
}
}
//return a rectangle for the device
function deviceRectangle(theDevice)
{
var centerpoint = convertXYPointToActual(newPointFromString(theDevice.location));
var delta = imageSize / 2;
var rect = {
spoint : newPointFromPair(centerpoint.x-delta, centerpoint.y-delta),
height : imageSize,
width : imageSize,
epoint : newPointFromPair(centerpoint.x + delta, centerpoint.y + delta),
center: centerpoint,
}
return rect;
}
function makeRectangle(x1, y1, deltax, deltay, offsetx = 0, offsety = 0) {
//The offset is for when we are drawing on a cached surface. It adds x or y to the point we are looking at
var struct = {
sx: x1,
sy: y1,
dx: x1 + deltax,
dy: y1 + deltay,
deltay: deltay,
deltax: deltax,
offsetx: offsetx,
offsety: offsety,
}
return struct;
}
function makeLine(x1, y1, x2, y2, offsetx = 0, offsety = 0) {
var linestruct = makeRectangle(x1, y1, x2 - x1, y2 - y1, offsetx, offsety);
//console.log("Creating a line: " + JSON.stringify(linestruct));
return linestruct;
}
//Make a structure to hold all our data
class actionStruct {
constructor(shapeText, shapePoints, theObject=null, funcLeftClick=null, funcRightClick=null, funcMouseover=null) {
this.shapeText= shapeText
this.shapePoints= structuredClone(shapePoints)
this.shapePoints.shapeText = shapeText;
this.theObject= theObject
this.funcLeftClick= funcLeftClick
this.funcRightClick= funcRightClick
this.funcMouseover= funcMouseover
}
}
function registerActionStruct(shapeText, shapePoints, theObject=null, funcLeftClick=null, funcRightClick=null, funcMouseover=null) {
//Make an object with all the data
var what = new actionStruct(shapeText, shapePoints, theObject, funcLeftClick, funcRightClick, funcMouseover);
//console.log("Pushing an action: " + shapeText);
//Push it onto the uiActions list
uiActions.unshift(what); //Put it at the beginning of the list
//console.log("ActionList: " + JSON.stringify(uiActions));
}
function clearActionStructs() {
uiActions = [];
}
function setStatus(text) {
ui_StatusText = text; //set the text.
}
//go through all highlights and print all of them
function printHighlights(countof="mouseover") {
var count = 0;
//console.log("Printing highlights. " + ui_HighlightArray.length)
for (var index = 0; index < ui_HighlightArray.length; index++) {
var highlight = ui_HighlightArray[index];
//console.log("trying to highlight something: " + JSON.stringify(highlight));
if (highlight.shapeName == countof) count++;
drawshape(highlight);
}
return countof; //the count of the item we were supposed to count
}
function drawshape(highlight) {
MainCanvas_ctx.fillStyle = highlight.shapeColor;
MainCanvas_ctx.globalAlpha = highlight.opaciticy; //mostly transparent
var oldWidth;
if (highlight.shapeText == "square")
MainCanvas_ctx.fillRect(highlight.shapePoints.sx, highlight.shapePoints.sy, highlight.shapePoints.deltax, highlight.shapePoints.deltay);
else if (highlight.shapeText == "line") {
oldWidth = MainCanvas_ctx.lineWidth;
MainCanvas_ctx.lineWidth += 6;
MainCanvas_ctx.strokeStyle = highlight.shapeColor;
MainCanvas_ctx.beginPath();
MainCanvas_ctx.moveTo(highlight.shapePoints.sx, highlight.shapePoints.sy);
MainCanvas_ctx.lineTo(highlight.shapePoints.dx, highlight.shapePoints.dy);
MainCanvas_ctx.stroke();
MainCanvas_ctx.lineWidth = oldWidth;
MainCanvas_ctx.strokeStyle = "black";
}
else if (highlight.shapeText == "selectbox") {
//console.log("Printing a selectbox");
MainCanvas_ctx.fillStyle = "green";
oldWidth = MainCanvas_ctx.lineWidth;
MainCanvas_ctx.lineWidth += 2;
MainCanvas_ctx.strokeStyle = "green";
MainCanvas_ctx.beginPath();
MainCanvas_ctx.moveTo(highlight.shapePoints.sx, highlight.shapePoints.sy);
MainCanvas_ctx.lineTo(highlight.shapePoints.dx, highlight.shapePoints.sy);
MainCanvas_ctx.lineTo(highlight.shapePoints.dx, highlight.shapePoints.dy);
MainCanvas_ctx.lineTo(highlight.shapePoints.sx, highlight.shapePoints.dy);
MainCanvas_ctx.lineTo(highlight.shapePoints.sx, highlight.shapePoints.sy);
MainCanvas_ctx.stroke();
MainCanvas_ctx.lineWidth = oldWidth;
MainCanvas_ctx.strokeStyle = "black";
}
MainCanvas_ctx.globalAlpha = 1.0; //reset
MainCanvas_ctx.fillStyle = "black"; //reset
}
function countHighlightsNamed(countof = "mouseover") {
var count = 0;
for (var index = 0; index < ui_HighlightArray.length; index++) {
if (ui_HighlightArray[index].shapeName == countof)
count++;
}
return countof; //the count of the item we were supposed to count
}
function returnHighlightShape(shapeText, shapePoints, shapeColor, shapeName, opaciticy = 0.4) {
//Create a highlight record with the needed info
var newhighlight = {
shapeText: shapeText,
shapePoints: structuredClone(shapePoints),
shapeColor: shapeColor,
shapeName: shapeName, //Used when we remove them later
opaciticy, opaciticy,
}
return newhighlight;
}
//There may be multiple things
function registerHighlightShape(shapeText, shapePoints, shapeColor, shapeName, opaciticy=0.4) {
//Create a highlight record with the needed info
var newhighlight = returnHighlightShape(shapeText, structuredClone(shapePoints), shapeColor, shapeName, opaciticy)
//console.log("registering a highlight: " + JSON.stringify(newhighlight));
//Add it to the list of highlights.
ui_HighlightArray.unshift(newhighlight);
return newhighlight;
}
function removeHighlightsNamed(shapeName) {
//console.log("Trying to remove " + shapeName + " in array of " + ui_HighlightArray.length);
for (var index = ui_HighlightArray.length; index >= 0; index--) {
if (ui_HighlightArray[index] == null) { }
else {
//console.log("Comparing " + shapeName + " in " + JSON.stringify(ui_HighlightArray[index]));
if (ui_HighlightArray[index].shapeName == shapeName) {
//console.log("removing " + shapeName + " at index:" + index + " " + ui_HighlightArray.length);
ui_HighlightArray.splice(index, 1); //remove it if found
}
}
}
}
function findHighlightsNamed(shapeName) {
for (var index = ui_HighlightArray.length; index >= 0; index--) {
if (ui_HighlightArray[index] == null) { }
else {
if (ui_HighlightArray[index].shapeName == shapeName)
return ui_HighlightArray[index];
}
}
return null; //null if not there
}
//This takes generic information for us to highlight the background
function generic_mouseoverHighlight(point, actionrec) {
//console.log("Found highlight " + JSON.stringify(actionrec));
//The point is the place where the mouse is, but the actionrec.shapePoints is the rectangle (or shape) we want to highlight
//var oldrec = structuredClone(ui_highlightRect);
var oldrec = findHighlightsNamed("mouseover");
var newrec = null;
//console.log("setting highlights to:" + JSON.stringify(actionrec));
removeHighlightsNamed("mouseover");
if (actionrec.shapeText == "square") {
//ui_highlightRect = structuredClone(actionrec.shapePoints);
//ui_highlightRect.shapeText = "square";
newrec = registerHighlightShape("square", actionrec.shapePoints, "white", "mouseover"); //opacity is default
//console.log("setting highlights to:" + JSON.stringify(ui_highlightRect));
}
if (actionrec.shapeText == "line") {
//ui_highlightRect = structuredClone(actionrec.shapePoints);
//ui_highlightRect.shapeText = "line";
newrec = registerHighlightShape("line", actionrec.shapePoints, "white", "mouseover"); //opacity is default
//console.log("setting highlights to:" + JSON.stringify(ui_highlightRect));
}
if (JSON.stringify(newrec) === JSON.stringify(oldrec)) {
//they are the same. Nothing to do
}
else
PrintScreen(); //two different areas. Need to print the screen
}
function device_clickOn(point, actionrec) {
if (actionrec.theObject !== null && actionrec.theObject.name !== null) {
ui_selectRect = structuredClone(actionrec.shapePoints);
//console.log("Setting select rect:" + JSON.stringify(ui_selectRect));
var ipaddresses = ipsFromDevice(actionrec.theObject);
var additional = "";
for (var x = 0; x < ipaddresses.length; x++) {
//Print the IP address if the type is correct.
//console.log(JSON.stringify(ipaddresses[x]));
switch (ipaddresses[x].nictype) {
case "eth":
case "management_interface":
//console.log("Found a " + ipaddresses[x].nictype)
additional += " " + ipaddresses[x].cidrip;
break;
}
}
if (deviceHasProblem(actionrec.theObject)) {
//If we know nothing, we change nothing
if (ui_helplevel > 0) {
if (ui_helplevel == 1) additional = " " + translator.getStr("NT_TstDscriptProblem");
else {
//here we get all the problem statements and combine them
errors = returnProblemStrings(actionrec.theObject);
additional = " " + errors.join(' - ');
}
}
}
setStatus(actionrec.theObject.hostname + additional);
//We probably do not want to do printecreen here, but we are doing it here now...
PrintScreen();
}
}
function Language(lang = null) {
var __construct = function () {
if (lang == null) {
lang = "en";
}
//console.log("Defining language:" + lang);
ui_language = lang;
return;
}()
this.getStr = function (str, defaultStr) {
var toget = 'language.' + ui_language + "." + str + ".value";
//console.log("Translating: " + toget);
var retStr = eval(toget);
if (typeof retStr != 'undefined') {
return retStr;
} else {
if (typeof defaultStr != 'undefined') {
return defaultStr;
} else {
toget = "language.en." + str;
//console.log("First translation failed, falling back to en: " + toget);
return eval(toget);
}
}
}
}