Compare commits

13 Commits

Author SHA1 Message Date
858bfef1bb Change how the text menu works. It is somewhat behind in that it does
not have all the same old functionality, but it uses menuitems now.
This will allow us to much-better utilize the textwindows.
2024-06-14 16:01:41 -05:00
deb5f29cee Changed some spaces to tabs. Happened automatically. 2024-06-11 09:22:13 -05:00
9aa26b82c6 make drawshape work better 2024-06-06 14:16:01 -07:00
726bafe580 Change drawshape to be drawhighlight as we pass it a highlight. 2024-06-06 13:59:59 -07:00
80c1abd5fe Trying to add a .editorconfig file for the Visual Studio editor. Visual
Studio keeps messing up the crlf.  Since I will mainly host this from a
Linux server, I want it to be just lf.
2024-06-03 15:41:16 -07:00
5ce6dc6d3e Moved actionStruct to be a class. Better that way 2024-05-31 17:12:00 -07:00
bf2e281c40 Use the translated version of the puzzle description. 2024-05-17 16:06:03 -06:00
98733d1ad5 Get basic problem translations. Ping only for now 2024-05-17 15:37:31 -06:00
0859bffc23 Put a selection-box around an item if we clicked on something 2024-05-17 10:33:33 -06:00
9be833dd2c Brought over the language strings from edunetworkbuilder and functions
for making language translation work.
2024-05-17 10:06:07 -06:00
0e9a6d1a15 Fixed a bug where clicking on a line would change how things were
viewed.  It turned out to be a rather bizarre bug based off of !== null
not working properly.
2024-05-16 12:13:41 -06:00
3e902cba95 Devices with problems properly have red background 2024-05-15 17:06:48 -06:00
77b034f845 Highlight items that have problems. 2024-05-10 15:03:52 -06:00
11 changed files with 9579 additions and 78 deletions

4
Web/.editorconfig Normal file
View File

@ -0,0 +1,4 @@
root = true
[*]
end_of_line = lf

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@
<script src="selectmenu.js"></script>
<script src="network.js"></script>
<script src="textwindow.js"></script>
<script src="language.js"></script>
<script src="ui.js"></script>
</body>
</html>

3995
Web/language.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,10 @@
//This file contains the information about the puzzle (network)
//Each puzzle is stored in the allpuzzles variable. We need to select one and use it
//We define this here, even though it is used primarily in the UI. We define its values here
var ui_helplevel = 0;
var puzzle=networkFromName("Level0-Ping");
//var puzzle=networkFromName("Level0-NeedsLink");
//var puzzle=networkFromName("Level0_NetworkLoop");
@ -32,7 +36,7 @@ function networkFromName(what)
if(allpuzzles[index].EduNetworkBuilder.Network.name == what)
{
console.log("Found " + what + " at index " + index);
return structuredClone(allpuzzles[index].EduNetworkBuilder.Network);
return networkFromIndex(index);
}
index++;
}
@ -40,11 +44,105 @@ function networkFromName(what)
function networkFromIndex(what)
{
if(typeof(what)==="number" && what >= 0 && what < allpuzzles.length){
return structuredClone(allpuzzles[what].EduNetworkBuilder.Network);
var newitem = structuredClone(allpuzzles[what].EduNetworkBuilder.Network);
console.log("It is an array:" + Array.isArray(newitem.nettest));
if (!Array.isArray(newitem.nettest)) {
var oneitem = newitem.nettest; //this is an object
newitem.nettest = [];
newitem.nettest.push(oneitem); //make it an one-item array.
}
//Set the help level to be whatever we need
if (newitem.startinghelplevel == "full") ui_helplevel = 3;
if (newitem.startinghelplevel == "hints") ui_helplevel = 2;
if (newitem.startinghelplevel == "basic") ui_helplevel = 1;
if (newitem.startinghelplevel == "none") ui_helplevel = 0;
console.log("Starting help level = " + ui_helplevel + " from " + newitem.startinghelplevel);
return newitem;
}
return null;
}
function deviceHasProblem(Device) {
var hostname = Device.hostname;
//console.log("Looking for tests on " + hostname + " and have: " + puzzle.nettest.length)
for (var index = 0; index < puzzle.nettest.length; index++) {
//console.log("Found test: " + JSON.stringify(puzzle.nettest));
if (puzzle.nettest[index].shost == hostname) {
if (puzzle.nettest[index].solved == null) {
//It has not yet been solved.
//console.log("Found problem on device: " + hostname);
return true;
}
}
}
return false;
}
function problemString(nettest) {
if (nettest == null) return "";
//The structure of a nettest
//"shost": "pc0",
//"dhost": "laptop0",
//"thetest": "SuccessfullyPings"
//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.");
switch (nettest.thetest) {
case "DHCPServerEnabled":
case "DeviceBlowsUpWithPower":
case "DeviceIsFrozen":
case "DeviceNeedsUPS":
case "FailedPing":
case "HelpRequest":
case "LockAll":
case "LockLocation":
case "LockNic":
case "LockVLANNames":
case "LockVLANsOnHost":
case "NeedsDefaultGW":
case "NeedsLinkToDevice":
case "NeedsLocalIPTo":
case "NeedsRouteToNet":
case "NeedsTaggedVLAN":
case "ReadContextHelp":
break;
case "SuccessfullyPings":
//level 0 is handled elsewhere
if (ui_helplevel == 2) return translator.getStr("NT_TstDiscriptPing");
if (ui_helplevel == 3) return translator.getStr("NT_TstDiscriptPing2") + nettest.dhost;
case "SuccessfullyPingsWithoutLoop":
case "SuccessfullyTraceroutes":
break;
}
return "";
}
function returnProblemStrings(Device) {
var hostname = Device.hostname;
var errors = [];
//console.log("Looking for tests on " + hostname + " and have: " + puzzle.nettest.length)
for (var index = 0; index < puzzle.nettest.length; index++) {
//console.log("Found test: " + JSON.stringify(puzzle.nettest));
if (puzzle.nettest[index].shost == hostname) {
if (puzzle.nettest[index].solved == null) {
//It has not yet been solved.
var error = problemString(puzzle.nettest[index]);
//console.log("We got a problem string:" + JSON.stringify(error));
if (error != "");
errors.push(error);
}
}
}
return errors;
}
function networkNamesMatchingText(textToMatch)
{
var list = [];

View File

@ -0,0 +1,40 @@
#!/usr/bin/perl
opendir(Dir, "Resources") || die "Can't open Resources directory: $!\n";
@files = grep(/edustrings/,readdir(Dir));
closedir(Dir);
open ($outfile, '>', "language.js") or die $!;
print($outfile "language = {\n");
foreach $file (@files) {
$lang = $file;
$lang =~ s/edustrings.//;
$lang =~ s/.json//;
print($outfile " $lang : {\n");
open my $info, "Resources/$file" or die "Could not open $file: $!";
while( my $line = <$info>) {
chomp($line);
if ( $line =~ /name": "(.*)",$/)
{
print($outfile " $1 : {");
}
if ( $line =~ /value": "(.*)",$/)
{
print($outfile "$line\n");
}
if ( $line =~ /value": "(.*)"$/) #if there is no comment
{
print($outfile "$line\n },\n");
}
if ( $line =~ /comment": "(.*)"$/)
{
print($outfile " $line\n },\n");
}
}
print($outfile " },\n"); #End the language file;
}
print($outfile "];\n"); #End the language variable definition
close($outfile);

View File

@ -0,0 +1,25 @@
#!/bin/bash
#
# Convert the EduNetworkBuilder language files into json
# Run this from the web directory, and make sure to have xq installed
if which xq >/dev/null; then
if [ -d Resources -a -d EduResources/languages ]; then
for a in EduResources/languages/*.resx; do
c=$a;
if [ $a = "EduResources/languages/edustrings.resx" ]; then
c="edustrings.en.resx"
fi
b=$(basename $c | sed 's/.resx/\.json/');
#if [ ! -e Resources/languages/$b ]; then
echo $b
xq '.root.data' $a |sed 's/\@name/name/' | grep -v 'xml:space' > Resources/$b
#fi
done
else
echo "You must be in the web directory of the EduNetworkBuilder git repo for this to work"
fi
else
echo "xq must be installed. This comes with the jq program"
echo "jq is used for working with json files and xq is the counterpart"
echo "that converts xml to json."
fi

View File

@ -17,7 +17,7 @@ var menuItemSize=50;
function InitializeSelectMenu() {
cachedSelectMenuCanvas = document.createElement('canvas');
cachedSelectMenuCanvas.width = menuItemSize;
console.log("length= " + selectMenuNames.length);
//console.log("length= " + selectMenuNames.length);
cachedSelectMenuCanvas.height = menuItemSize * selectMenuNames.length;
var cSMCctx = cachedSelectMenuCanvas.getContext('2d');
var starty = 0;

View File

@ -208,18 +208,202 @@ function PrintPuzzleSelectMenu(level=0)
{
var levellist=networkNamesMatchingText("Level"+level);
//console.log("list is this long: " + levellist.length);
textMenuPrint(levellist, -1, tmLastHighlightedIndex);
tmPuzzleSelectMenuLevel=level;
//textMenuPrint(levellist, -1, tmLastHighlightedIndex);
//tmPuzzleSelectMenuLevel=level;
//
var local_menuitems = [];
for (var i = 1; i < levellist.length; i++) {
var item = new menuitem(null, levellist[i], levellist[i], null, null, textMenu_PuzzleClick)
local_menuitems.push(item);
}
var local_menu = new menuclass(null);
local_menu.items = local_menuitems;
menuPrint(local_menu);
}
function textMenu_PuzzleClick(text, name, source, dest) {
//If we get here, someone clicked on a puzzle name. Select it and move on
//We are in puzzle-select mode and clicked somewhere.
//if (text == null) { } //!== does not work properly
//else {
// console.log("Clicked on puzzle: " + text);
// uiMode = 1;
// switchPuzzle(text);
//}
}
function textMenu_HandleMouseMove(evt)
{
var highlighted_index = Math.floor(((evt.pageY - tmOutsideYMargin) - (tmTextHeight/3)) / tmTextHeight);
if(tmLastHighlightedIndex != highlighted_index)
{
//the index has changed
console.log("index = " + highlighted_index);
tmLastHighlightedIndex = highlighted_index;
PrintPuzzleSelectMenu(tmPuzzleSelectMenuLevel);
//var highlighted_index = Math.floor(((evt.pageY - tmOutsideYMargin) - (tmTextHeight/3)) / tmTextHeight);
//if(tmLastHighlightedIndex != highlighted_index)
//{
// //the index has changed
// console.log("index = " + highlighted_index);
// tmLastHighlightedIndex = highlighted_index;
// PrintPuzzleSelectMenu(tmPuzzleSelectMenuLevel);
//}
}
class menuitem {
constructor(rectangle, shownText, payloadName = null, payloadSource = null, payloadDest = null, clickFunc=null) {
this.rectangle = rectangle
this.shownText = shownText
this.payloadName = payloadName //The command, such as 'delete', 'power-on', 'ping', etc
this.payloadSource = payloadSource //The link, device, or original item.
this.payloadDest = payloadDest //The destination device, etc. Often null unless we are pinging or tracert
this.clickFunc = clickFunc
}
}
//Our menuclass will have a menu. We need to be able to have cascading menus (one on top of the other)
//so we can return to a past menu if we have moved on to a child menu.
class menuclass {
constructor(sourceItem) {
this.SourceItem = sourceItem
this.hmargin = 10 //horizontal margin on both left and right
this.vmargin = 10 //virtical margin on both top and bottom
this.backcolor = "grey" //The background color
this.font = "20px serif" //font and size
this.textcolor = "black" //Font color
this.items = [] //An array of menuitems
this.TextYGap = 3; //The gap to add to the size
}
}
function menuPrint(menu, menutop = 0, highlightedindex = -1) {
//the menu is the menuclass that holds everything
//menutop is the top=most item. If we scroll up and down, this changes.
//highlighted index is the item that has been moused-over. When this changes, re-draw the menu
PrintScreen(0); //Print the network, then we can lay over it
//This menu covers the entire place.
cachedTextMenuCanvas = document.createElement('canvas');
cachedTextMenuCanvas.width = MainCanvas.width - (tmOutsideXMargin * 2);
cachedTextMenuCanvas.height = MainCanvas.height - (tmOutsideYMargin * 2);
//Get the context
var cTMCctx = cachedTextMenuCanvas.getContext('2d');
var tw_rect;
var tw_width=0; //the width of the menu alltogether
var tw_height=0; //the height of the menu alltogether
var tw_itemHeight=0; //the height of both the font and margin spacing
var tw_rect; //the rectangle we end up using
//We need to figure out the size of the menu.
//Do we have an item to print? If so, add that at top
if (menu.SourceItem == null) {
//!== null does not work right
}
else {
tw_height = imageSize + 10;
}
var tw_startY = tw_height;
//Calculate the size of each text line
//Add spacing. If we are larger than the alloted space, add arrows at top and bottom
//Then we can fill in the area based on all of this.
cTMCctx.strokeStyle = menu.textcolor;
cTMCctx.font = menu.font;
var metrics = cTMCctx.measureText("test");
var yHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent + menu.TextYGap; //the hight of the default font and gap
var tw_TextHeight = yHeight; //store it for use
var maxWidth = 0;
//determine max width (width of longest text line)
for (var index = 0; index < menu.items.length; index++) {
var tmetrics = cTMCctx.measureText(menu.items[index].shownText);
var xWidth = tmetrics.width;
if (xWidth > maxWidth) maxWidth = xWidth;
}
maxWidth = maxWidth + 20 + menu.hmargin;
if (maxWidth > cachedTextMenuCanvas.width) maxWidth = cachedTextMenuCanvas.width;
tw_width = maxWidth;
//determine height (if we have more items than fit, figure out what will fit)
tw_height += menu.items.length * yHeight;
if(tw_height > cachedTextMenuCanvas.height) tw_height = cachedTextMenuCanvas.height;
//Now that we have the width and height, center it
var x = (cachedTextMenuCanvas.width - tw_width) / 2;
var y = (cachedTextMenuCanvas.height - tw_height) / 2;
//make a rectangle of the correct size
//Use that rectangle to place the closing X at the top
tw_rect = makeRectangle(x, y, tw_width, tw_height);
//fill in the whole thing with white and opaque
drawshape("square", makeRectangle(0, 0, cachedTextMenuCanvas.width, cachedTextMenuCanvas.height), "white", .5, cTMCctx);
//Fill in the background, nearly fully but showing a very little behind
drawshape("square", tw_rect, menu.backcolor, .9, cTMCctx);
//Put the X there so we can click on it
rect = makeRectangle(cachedTextMenuCanvas.width - tmScrollBarWidth, y, tmScrollBarWidth, tmMenuBarHight, tmOutsideXMargin, tmOutsideYMargin);
cTMCctx.drawImage(imageFromName("x"), rect.sx, rect.sy, rect.deltax, rect.deltay);
registerActionStruct("square", rect, null, textwindow_XClick);
//Put the UpArrow there so we can click on it
cTMCctx.drawImage(imageFromName("ArrowUp"), cachedTextMenuCanvas.width - tmScrollBarWidth, tmMenuBarHight, tmScrollBarWidth, tmMenuBarHight);
//Put the DownArrow there so we can click on it
cTMCctx.drawImage(imageFromName("ArrowDown"), cachedTextMenuCanvas.width - tmScrollBarWidth, cachedTextMenuCanvas.height - tmMenuBarHight, tmScrollBarWidth, tmMenuBarHight);
//Create and Draw the menu bar
cTMCctx.beginPath();
cTMCctx.moveTo(cachedTextMenuCanvas.width - tmScrollBarWidth, 0);
cTMCctx.lineTo(cachedTextMenuCanvas.width - tmScrollBarWidth, cachedTextMenuCanvas.height);
cTMCctx.strokeStyle = "white";
cTMCctx.stroke();
//horizontal line under the X
cTMCctx.beginPath();
cTMCctx.moveTo(cachedTextMenuCanvas.width - tmScrollBarWidth, tmMenuBarHight);
cTMCctx.lineTo(cachedTextMenuCanvas.width, tmMenuBarHight);
cTMCctx.strokeStyle = "white";
cTMCctx.stroke();
var oldfill = cTMCctx.fillStyle;
var oldstroke = cTMCctx.strokeStyle;
cTMCctx.font = menu.font;
cTMCctx.fillStyle = menu.textcolor;
cTMCctx.strokeStyle = menu.textcolor;
for (var index = menutop; index < menu.items.length; index++) {
var ty = tw_startY + (tw_TextHeight * (index - menutop));
//x is already defined
cTMCctx.fillText(menu.items[index].shownText, x, ty);
metrics = cTMCctx.measureText(menu.items[index].shownText);
var trect = makeRectangle(x + 20, ty, metrics.width, tw_TextHeight);
menu.items[index].rectangle = trect;
registerActionStruct("square", trect, menu.items[index], puzzle_clickOn, null, generic_mouseoverHighlight);
}
cTMCctx.fillStyle = oldfill;
cTMCctx.strokeStyle = oldstroke;
MainCanvas_ctx.globalAlpha = 0.9; //some transparancy
MainCanvas_ctx.drawImage(cachedTextMenuCanvas, tmOutsideXMargin, tmOutsideYMargin)
MainCanvas_ctx.globalAlpha = 1; //reset transparancy
}
function puzzle_clickOn(point, actionrec) {
console.log("clicking on puzzle:" + actionrec.theObject.shownText);
uiMode = 1;
switchPuzzle(actionrec.theObject.shownText);
}

284
Web/ui.js
View File

@ -12,10 +12,12 @@ 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;
@ -45,7 +47,7 @@ const imageCollection = loadImages(
"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/menu.png", "img/thumb.png",
"img/queryuser.png", "img/thumb.png",
],
InitializeGameMenu // this is called when all images have loaded.
);
@ -99,7 +101,7 @@ function PrintScreen(WhatPassedIn=-1)
//Clear out any old ActionStructs. They will get filled in as we print the screen.
clearActionStructs();
console.log("PrintingScreen for mode: " + what);
//console.log("PrintingScreen for mode: " + what);
var rect;
if(what == 0)
@ -109,29 +111,8 @@ function PrintScreen(WhatPassedIn=-1)
MainCanvas_ctx.fillStyle = maincanvasBackground;
MainCanvas_ctx.fillRect(0, 0, MainCanvas.width, MainCanvas.height);
////Do any highlight we need to
//if (ui_highlightRect !== null) {
// //console.log("trying to highlight something: " + JSON.stringify(ui_highlightRect));
// MainCanvas_ctx.fillStyle = "white";
// MainCanvas_ctx.globalAlpha = 0.4; //mostly transparent
// if (ui_highlightRect.shapeText == "square")
// MainCanvas_ctx.fillRect(ui_highlightRect.sx, ui_highlightRect.sy, ui_highlightRect.deltax, ui_highlightRect.deltay);
// else if (ui_highlightRect.shapeText == "line") {
// var oldWidth = MainCanvas_ctx.lineWidth;
// MainCanvas_ctx.lineWidth += 6;
// MainCanvas_ctx.strokeStyle = "white";
// MainCanvas_ctx.beginPath();
// MainCanvas_ctx.moveTo(ui_highlightRect.sx, ui_highlightRect.sy);
// MainCanvas_ctx.lineTo(ui_highlightRect.dx, ui_highlightRect.dy);
// MainCanvas_ctx.stroke();
// MainCanvas_ctx.lineWidth = oldWidth;
// MainCanvas_ctx.strokeStyle = "black";
// }
// MainCanvas_ctx.globalAlpha = 1.0; //reset
// MainCanvas_ctx.fillStyle = "black"; //reset
// ui_HadHighlight = true;
//}
//else ui_HadHighlight = false;
//Check for device highlights
checkDevicesForIssues();
//print highlights. If we have mouseover highlights, note that.
if (printHighlights("mouseover") > 0) ui_HadHighlight = true;
@ -153,6 +134,23 @@ function PrintScreen(WhatPassedIn=-1)
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 drawhighlight(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;
@ -179,6 +177,13 @@ function PrintScreen(WhatPassedIn=-1)
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);
drawhighlight(tmp_select);
}
drawSelectMenu();
PrintAllNetworkLinks();
PrintAllNetworkDevices();
@ -186,7 +191,8 @@ function PrintScreen(WhatPassedIn=-1)
else if(what == 1) //PuzzleDescription/Info
{
//Display the text about the puzzle
textMenuPrint(puzzle.en_message);
console.log("Using language: " + ui_language);
textMenuPrint(eval('puzzle.' + ui_language + '_message'));
}
else if(what == 2) //PuzzleSelect
{
@ -232,9 +238,10 @@ function CheckForActions(actionPoint, action) {
var checkit = false;
var inside = false;
for (var index = 0; index < uiActions.length; index++) {
if (action == "leftclick" && uiActions[index].funcLeftClick !== null) checkit = true;
if (action == "rightclick" && uiActions[index].funcRightClick !== null) checkit = true;
if (action == "mouseover" && uiActions[index].funcMouseover !== null) checkit = true;
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) {
@ -262,14 +269,16 @@ function CheckForActions(actionPoint, action) {
//console.log("Is inside");
switch (action) {
case "leftclick":
if (checklocation.funcLeftClick != null) {
if (checklocation.funcLeftClick == null) { }
else {
checklocation.funcLeftClick(actionPoint, checklocation);
//console.log("Successfully did a UI action");
//console.log("Successfully did a left-click UI action");
return true;
}
break;
case "mouseover":
if (checklocation.funcMouseover != null) {
if (checklocation.funcMouseover == null) { }
else {
checklocation.funcMouseover(actionPoint, checklocation);
//console.log("Successfully did a UI action");
return true;
@ -303,7 +312,7 @@ function distance(x1, y1, x2, y2) {
function handleMouseUp(evt)
{
//evt.preventDefault();
mouseIsDown=false;
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);
@ -320,10 +329,17 @@ function handleMouseUp(evt)
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);
else if (uiMode == 2) TextWindow_handleMouseUp(evt);
if (needsrefresh) {
if (ui_selectRect == null) setStatus(""); //we clicked on nothing
PrintScreen();
}
}
}
@ -345,6 +361,19 @@ function ui_eyeLeftClick(evt) {
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
@ -460,6 +489,12 @@ function PrintNetworkDevice(ToPrint)
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);
drawhighlight(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);
@ -505,11 +540,34 @@ function PrintNetworkDevice(ToPrint)
}
}
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;
let index = 0;
while (index < puzzle.device.length) {
PrintNetworkDevice(puzzle.device[index]);
index++;
@ -630,22 +688,22 @@ function makeLine(x1, y1, x2, y2, offsetx = 0, offsety = 0) {
}
//Make a structure to hold all our data
function actionStruct(shapeText, shapePoints, theObject=null, funcLeftClick=null, funcRightClick=null, funcMouseover=null) {
var struct = {
shapeText: shapeText,
shapePoints: structuredClone(shapePoints),
theObject: theObject,
funcLeftClick: funcLeftClick,
funcRightClick: funcRightClick,
funcMouseover: funcMouseover,
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
}
shapePoints.shapeText = shapeText;
return struct;
}
function registerActionStruct(shapeText, shapePoints, theObject=null, funcLeftClick=null, funcRightClick=null, funcMouseover=null) {
//Make an object with all the data
var what = actionStruct(shapeText, shapePoints, theObject, funcLeftClick, funcRightClick, funcMouseover);
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
@ -664,31 +722,63 @@ function setStatus(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++;
MainCanvas_ctx.fillStyle = highlight.shapeColor;
MainCanvas_ctx.globalAlpha = highlight.opaciticy; //mostly transparent
if (highlight.shapeText == "square")
MainCanvas_ctx.fillRect(highlight.shapePoints.sx, highlight.shapePoints.sy, highlight.shapePoints.deltax, highlight.shapePoints.deltay);
else if (highlight.shapeText == "line") {
var 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";
}
MainCanvas_ctx.globalAlpha = 1.0; //reset
MainCanvas_ctx.fillStyle = "black"; //reset
drawhighlight(highlight);
}
return countof; //the count of the item we were supposed to count
}
function drawhighlight(highlight, canvas = null) {
if (canvas == null)
canvas = MainCanvas_ctx;
canvas.fillStyle = highlight.shapeColor;
canvas.globalAlpha = highlight.opaciticy; //mostly transparent
var oldWidth;
if (highlight.shapeText == "square")
canvas.fillRect(highlight.shapePoints.sx, highlight.shapePoints.sy, highlight.shapePoints.deltax, highlight.shapePoints.deltay);
else if (highlight.shapeText == "line") {
oldWidth = canvas.lineWidth;
canvas.lineWidth += 6;
canvas.strokeStyle = highlight.shapeColor;
canvas.beginPath();
canvas.moveTo(highlight.shapePoints.sx, highlight.shapePoints.sy);
canvas.lineTo(highlight.shapePoints.dx, highlight.shapePoints.dy);
canvas.stroke();
canvas.lineWidth = oldWidth;
canvas.strokeStyle = "black";
}
else if (highlight.shapeText == "selectbox") {
//console.log("Printing a selectbox");
canvas.fillStyle = "green";
oldWidth = canvas.lineWidth;
canvas.lineWidth += 2;
canvas.strokeStyle = "green";
canvas.beginPath();
canvas.moveTo(highlight.shapePoints.sx, highlight.shapePoints.sy);
canvas.lineTo(highlight.shapePoints.dx, highlight.shapePoints.sy);
canvas.lineTo(highlight.shapePoints.dx, highlight.shapePoints.dy);
canvas.lineTo(highlight.shapePoints.sx, highlight.shapePoints.dy);
canvas.lineTo(highlight.shapePoints.sx, highlight.shapePoints.sy);
canvas.stroke();
canvas.lineWidth = oldWidth;
canvas.strokeStyle = "black";
}
canvas.globalAlpha = 1.0; //reset
canvas.fillStyle = "black"; //reset
}
//We use drawhighlight to draw one-off shapes
function drawshape( shape, rect, color, opaciticy = 0.4, canvas = null) {
if (canvas == null)
canvas = MainCanvas_ctx;
var tmp_queryhighlight = returnHighlightShape(shape, rect, color, "none", opaciticy);
drawhighlight(tmp_queryhighlight, canvas);
}
function countHighlightsNamed(countof = "mouseover") {
var count = 0;
for (var index = 0; index < ui_HighlightArray.length; index++) {
@ -698,8 +788,7 @@ function countHighlightsNamed(countof = "mouseover") {
return countof; //the count of the item we were supposed to count
}
//There may be multiple things
function registerHighlightShape(shapeText, shapePoints, shapeColor, shapeName, opaciticy=0.4) {
function returnHighlightShape(shapeText, shapePoints, shapeColor, shapeName, opaciticy = 0.4) {
//Create a highlight record with the needed info
var newhighlight = {
shapeText: shapeText,
@ -708,6 +797,13 @@ function registerHighlightShape(shapeText, shapePoints, shapeColor, shapeName, o
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);
@ -769,8 +865,64 @@ function generic_mouseoverHighlight(point, actionrec) {
function device_clickOn(point, actionrec) {
if (actionrec.theObject !== null && actionrec.theObject.name !== null) {
setStatus(actionrec.theObject.hostname);
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);
}
}
}
}