Compare commits
25 Commits
dc741e8c0b
...
web
Author | SHA1 | Date | |
---|---|---|---|
858bfef1bb | |||
deb5f29cee | |||
9aa26b82c6 | |||
726bafe580 | |||
80c1abd5fe | |||
5ce6dc6d3e | |||
bf2e281c40 | |||
98733d1ad5 | |||
0859bffc23 | |||
9be833dd2c | |||
0e9a6d1a15 | |||
3e902cba95 | |||
77b034f845 | |||
f3ed276ca9 | |||
7b57cbe97a | |||
ee0a3f9255 | |||
a19cb99b9d | |||
6119432875 | |||
84685e3bd4 | |||
d7f73f04d8 | |||
50b4843d76 | |||
b978a3abb0 | |||
4ec5b370e9 | |||
50099ee4ef | |||
df520fcce6 |
4
Web/.editorconfig
Normal file
4
Web/.editorconfig
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
root = true
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
2606
Web/Resources/edustrings.en.json
Normal file
2606
Web/Resources/edustrings.en.json
Normal file
File diff suppressed because it is too large
Load Diff
2396
Web/Resources/edustrings.fr.json
Normal file
2396
Web/Resources/edustrings.fr.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Web/img/thumb.png
Normal file
BIN
Web/img/thumb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
@ -25,12 +25,13 @@
|
|||||||
</form>
|
</form>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<canvas id='MainCanvas' width='700 ' height='400' style="border:1px solid #000000;">
|
<canvas id='MainCanvas' width='700 ' height='400' style="border:1px solid #000000;"></canvas>
|
||||||
|
|
||||||
<script src="allpuzzles.js"></script>
|
<script src="allpuzzles.js"></script>
|
||||||
<script src="selectmenu.js"></script>
|
<script src="selectmenu.js"></script>
|
||||||
<script src="network.js"></script>
|
<script src="network.js"></script>
|
||||||
<script src="textwindow.js"></script>
|
<script src="textwindow.js"></script>
|
||||||
|
<script src="language.js"></script>
|
||||||
<script src="ui.js"></script>
|
<script src="ui.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
3995
Web/language.js
Normal file
3995
Web/language.js
Normal file
File diff suppressed because it is too large
Load Diff
164
Web/network.js
164
Web/network.js
@ -1,6 +1,10 @@
|
|||||||
//This file contains the information about the puzzle (network)
|
//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
|
//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-Ping");
|
||||||
//var puzzle=networkFromName("Level0-NeedsLink");
|
//var puzzle=networkFromName("Level0-NeedsLink");
|
||||||
//var puzzle=networkFromName("Level0_NetworkLoop");
|
//var puzzle=networkFromName("Level0_NetworkLoop");
|
||||||
@ -32,7 +36,7 @@ function networkFromName(what)
|
|||||||
if(allpuzzles[index].EduNetworkBuilder.Network.name == what)
|
if(allpuzzles[index].EduNetworkBuilder.Network.name == what)
|
||||||
{
|
{
|
||||||
console.log("Found " + what + " at index " + index);
|
console.log("Found " + what + " at index " + index);
|
||||||
return structuredClone(allpuzzles[index].EduNetworkBuilder.Network);
|
return networkFromIndex(index);
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
@ -40,11 +44,105 @@ function networkFromName(what)
|
|||||||
function networkFromIndex(what)
|
function networkFromIndex(what)
|
||||||
{
|
{
|
||||||
if(typeof(what)==="number" && what >= 0 && what < allpuzzles.length){
|
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;
|
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)
|
function networkNamesMatchingText(textToMatch)
|
||||||
{
|
{
|
||||||
var list = [];
|
var list = [];
|
||||||
@ -86,3 +184,65 @@ function deviceFromID(what)
|
|||||||
}
|
}
|
||||||
return null; //No match. return a null value
|
return null; //No match. return a null value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//return a list of all the ip addresses a device has
|
||||||
|
function ipsFromDevice(what) {
|
||||||
|
var ipaddresses = [];
|
||||||
|
for (var i = 0; i < what.nic.length; i++) {
|
||||||
|
ipaddresses = ipaddresses.concat(ipsFromNic(what.nic[i]));
|
||||||
|
}
|
||||||
|
//console.log("Adding to nics " + ipaddresses.length);
|
||||||
|
return ipaddresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ipsFromInterface(what, nictype) {
|
||||||
|
var ipaddresses = [];
|
||||||
|
if (typeof (what.myip) === "array") {
|
||||||
|
for (var x = 0; x < what.myip.length; x++) {
|
||||||
|
var one = {
|
||||||
|
nic: what.nicname,
|
||||||
|
ip: what.myip[x].ip,
|
||||||
|
mask: what.myip[x].mask,
|
||||||
|
cidrip: what.myip[x].ip + "/" + NetmaskToCIDR(what.myip[x].mask),
|
||||||
|
nictype: nictype,
|
||||||
|
};
|
||||||
|
ipaddresses.push(one);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (typeof (what.myip) === "object") {
|
||||||
|
var one = {
|
||||||
|
nic: what.nicname,
|
||||||
|
ip: what.myip.ip,
|
||||||
|
mask: what.myip.mask,
|
||||||
|
cidrip: what.myip.ip + "/" + NetmaskToCIDR(what.myip.mask),
|
||||||
|
nictype: nictype,
|
||||||
|
};
|
||||||
|
ipaddresses.push(one);
|
||||||
|
//console.log("found an ip object: " + JSON.stringify(one) + " " + nictype);
|
||||||
|
}
|
||||||
|
return ipaddresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ipsFromNic(what) {
|
||||||
|
var ipaddresses = [];
|
||||||
|
//console.log("Looking at a nic: " + JSON.stringify(what));
|
||||||
|
if (typeof (what.interface) === "array") {
|
||||||
|
for (var i = 0; i < what.interface.length; i++) {
|
||||||
|
//console.log("Trying to add a nic." + what.interface[i].nicname);
|
||||||
|
ipaddresses=ipaddresses.concat(ipsFromInterface(what.interface[i],what.nictype[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (typeof (what.interface) === "object")
|
||||||
|
ipaddresses=ipaddresses.concat(ipsFromInterface(what.interface, what.nictype[0]));
|
||||||
|
|
||||||
|
return ipaddresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
function NetmaskToCIDR(mask) {
|
||||||
|
var cidr = 0;
|
||||||
|
var maskNodes = mask.match(/(\d+)/g);
|
||||||
|
for (var i in maskNodes) {
|
||||||
|
cidr += (((maskNodes[i] >>> 0).toString(2)).match(/1/g) || []).length;
|
||||||
|
}
|
||||||
|
return cidr;
|
||||||
|
}
|
40
Web/scripts/BuildLanguage.pl
Normal file
40
Web/scripts/BuildLanguage.pl
Normal 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);
|
||||||
|
|
25
Web/scripts/ConvertResx2Json.sh
Normal file
25
Web/scripts/ConvertResx2Json.sh
Normal 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
|
@ -17,7 +17,7 @@ var menuItemSize=50;
|
|||||||
function InitializeSelectMenu() {
|
function InitializeSelectMenu() {
|
||||||
cachedSelectMenuCanvas = document.createElement('canvas');
|
cachedSelectMenuCanvas = document.createElement('canvas');
|
||||||
cachedSelectMenuCanvas.width = menuItemSize;
|
cachedSelectMenuCanvas.width = menuItemSize;
|
||||||
console.log("length= " + selectMenuNames.length);
|
//console.log("length= " + selectMenuNames.length);
|
||||||
cachedSelectMenuCanvas.height = menuItemSize * selectMenuNames.length;
|
cachedSelectMenuCanvas.height = menuItemSize * selectMenuNames.length;
|
||||||
var cSMCctx = cachedSelectMenuCanvas.getContext('2d');
|
var cSMCctx = cachedSelectMenuCanvas.getContext('2d');
|
||||||
var starty = 0;
|
var starty = 0;
|
||||||
|
@ -31,13 +31,17 @@ function textMenuPrint(TextToPrint, selectedindex = -1, highlightedindex = -1)
|
|||||||
}
|
}
|
||||||
//If we get here, it is already created. Get the context
|
//If we get here, it is already created. Get the context
|
||||||
var cTMCctx = cachedTextMenuCanvas.getContext('2d');
|
var cTMCctx = cachedTextMenuCanvas.getContext('2d');
|
||||||
|
var rect;
|
||||||
|
|
||||||
//Fill in the background
|
//Fill in the background
|
||||||
cTMCctx.fillStyle = tmWindowBackground;
|
cTMCctx.fillStyle = tmWindowBackground;
|
||||||
cTMCctx.fillRect(0,0, cachedTextMenuCanvas.width, cachedTextMenuCanvas.height);
|
cTMCctx.fillRect(0,0, cachedTextMenuCanvas.width, cachedTextMenuCanvas.height);
|
||||||
|
|
||||||
//Put the X there so we can click on it
|
//Put the X there so we can click on it
|
||||||
cTMCctx.drawImage(imageFromName("x"),cachedTextMenuCanvas.width - tmScrollBarWidth,0,tmScrollBarWidth,tmMenuBarHight);
|
rect = makeRectangle(cachedTextMenuCanvas.width - tmScrollBarWidth, 0, tmScrollBarWidth, tmMenuBarHight, tmOutsideXMargin, tmOutsideYMargin);
|
||||||
|
cTMCctx.drawImage(imageFromName("x"), rect.sx, rect.sy, rect.deltax, rect.deltay);
|
||||||
|
registerActionStruct("square", rect, null, textwindow_XClick);
|
||||||
|
|
||||||
|
|
||||||
//Put the DownArrow there so we can click on it
|
//Put the DownArrow there so we can click on it
|
||||||
cTMCctx.drawImage(imageFromName("ArrowUp"),cachedTextMenuCanvas.width - tmScrollBarWidth,tmMenuBarHight,tmScrollBarWidth,tmMenuBarHight);
|
cTMCctx.drawImage(imageFromName("ArrowUp"),cachedTextMenuCanvas.width - tmScrollBarWidth,tmMenuBarHight,tmScrollBarWidth,tmMenuBarHight);
|
||||||
@ -165,15 +169,7 @@ function TextWindow_handleMouseUp(evt)
|
|||||||
|
|
||||||
//We clicked the X
|
//We clicked the X
|
||||||
|
|
||||||
//Dispose of the text window
|
textwindow_XClick();
|
||||||
uiMode=0;
|
|
||||||
|
|
||||||
//dispose of temp canvas; will recreate later if needed
|
|
||||||
cachedTextMenuCanvas = null;
|
|
||||||
cachedTextMenuTextCanvas = null;
|
|
||||||
|
|
||||||
//Redraw the screen
|
|
||||||
PrintScreen();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -195,22 +191,219 @@ function TextWindow_handleMouseUp(evt)
|
|||||||
mouseDidMovement=false; //reset it after we raise the button
|
mouseDidMovement=false; //reset it after we raise the button
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function textwindow_XClick(point, object) {
|
||||||
|
//When the x is clicked, we do not care about the position or object. There is no object
|
||||||
|
//Dispose of the text window
|
||||||
|
uiMode = 0;
|
||||||
|
|
||||||
|
//dispose of temp canvas; will recreate later if needed
|
||||||
|
cachedTextMenuCanvas = null;
|
||||||
|
cachedTextMenuTextCanvas = null;
|
||||||
|
|
||||||
|
//Redraw the screen
|
||||||
|
PrintScreen();
|
||||||
|
}
|
||||||
|
|
||||||
function PrintPuzzleSelectMenu(level=0)
|
function PrintPuzzleSelectMenu(level=0)
|
||||||
{
|
{
|
||||||
var levellist=networkNamesMatchingText("Level"+level);
|
var levellist=networkNamesMatchingText("Level"+level);
|
||||||
//console.log("list is this long: " + levellist.length);
|
//console.log("list is this long: " + levellist.length);
|
||||||
textMenuPrint(levellist, -1, tmLastHighlightedIndex);
|
//textMenuPrint(levellist, -1, tmLastHighlightedIndex);
|
||||||
tmPuzzleSelectMenuLevel=level;
|
//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)
|
function textMenu_HandleMouseMove(evt)
|
||||||
{
|
{
|
||||||
var highlighted_index = Math.floor(((evt.pageY - tmOutsideYMargin) - (tmTextHeight/3)) / tmTextHeight);
|
//var highlighted_index = Math.floor(((evt.pageY - tmOutsideYMargin) - (tmTextHeight/3)) / tmTextHeight);
|
||||||
if(tmLastHighlightedIndex != highlighted_index)
|
//if(tmLastHighlightedIndex != highlighted_index)
|
||||||
{
|
//{
|
||||||
//the index has changed
|
// //the index has changed
|
||||||
console.log("index = " + highlighted_index);
|
// console.log("index = " + highlighted_index);
|
||||||
tmLastHighlightedIndex = highlighted_index;
|
// tmLastHighlightedIndex = highlighted_index;
|
||||||
PrintPuzzleSelectMenu(tmPuzzleSelectMenuLevel);
|
// 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);
|
||||||
|
}
|
639
Web/ui.js
639
Web/ui.js
@ -8,7 +8,16 @@ var mouseIsDown=false;
|
|||||||
var mouseDownLocation;
|
var mouseDownLocation;
|
||||||
var mouseDidMovement=false;
|
var mouseDidMovement=false;
|
||||||
var imageSize=40;
|
var imageSize=40;
|
||||||
var small_button_size=20;
|
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
|
//The user interface mode. 0=network, 1=network information, 2=puzzle-selection menu
|
||||||
var uiMode=1;
|
var uiMode=1;
|
||||||
@ -24,7 +33,9 @@ const imageCollection = loadImages(
|
|||||||
"shapes", "square", "switch",
|
"shapes", "square", "switch",
|
||||||
"tablet", "tree", "vidimage",
|
"tablet", "tree", "vidimage",
|
||||||
"wap", "wbridge", "wrepeater",
|
"wap", "wbridge", "wrepeater",
|
||||||
"wrouter", "x", "info", "menu"],
|
"wrouter", "x", "info", "menu",
|
||||||
|
"eye", "queryuser", "thumb",
|
||||||
|
],
|
||||||
["img/ArrowUp.png", "img/ArrowDown.png", "img/Animations.png",
|
["img/ArrowUp.png", "img/ArrowDown.png", "img/Animations.png",
|
||||||
"img/BurnMark.png", "img/cellphone.png", "img/Circle.png",
|
"img/BurnMark.png", "img/cellphone.png", "img/Circle.png",
|
||||||
"img/Copier.png", "img/firewall.png", "img/fluorescent.png",
|
"img/Copier.png", "img/firewall.png", "img/fluorescent.png",
|
||||||
@ -35,7 +46,9 @@ const imageCollection = loadImages(
|
|||||||
"img/Switch.png", "img/tablet.png", "img/tree.png",
|
"img/Switch.png", "img/tablet.png", "img/tree.png",
|
||||||
"img/VidImage.png", "img/WAP.png", "img/WBridge.png",
|
"img/VidImage.png", "img/WAP.png", "img/WBridge.png",
|
||||||
"img/WRepeater.png", "img/WRouter.png", "img/X.png",
|
"img/WRepeater.png", "img/WRouter.png", "img/X.png",
|
||||||
"img/info.png", "img/menu.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.
|
InitializeGameMenu // this is called when all images have loaded.
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -85,7 +98,11 @@ function PrintScreen(WhatPassedIn=-1)
|
|||||||
var what=uiMode;
|
var what=uiMode;
|
||||||
if(WhatPassedIn >=0) what=WhatPassedIn;
|
if(WhatPassedIn >=0) what=WhatPassedIn;
|
||||||
|
|
||||||
console.log("PrintingScreen for mode: " + what);
|
//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)
|
if(what == 0)
|
||||||
{
|
{
|
||||||
@ -94,12 +111,78 @@ function PrintScreen(WhatPassedIn=-1)
|
|||||||
MainCanvas_ctx.fillStyle = maincanvasBackground;
|
MainCanvas_ctx.fillStyle = maincanvasBackground;
|
||||||
MainCanvas_ctx.fillRect(0, 0, MainCanvas.width, MainCanvas.height);
|
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
|
//Draw the puzzle-select button
|
||||||
//Put the X there so we can click on it
|
//Put the X there so we can click on it
|
||||||
MainCanvas_ctx.drawImage(imageFromName("menu"),MainCanvas.width - small_button_size,0,small_button_size,small_button_size);
|
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
|
//Draw the info button
|
||||||
MainCanvas_ctx.drawImage(imageFromName("info"),MainCanvas.width - small_button_size,small_button_size,small_button_size,small_button_size);
|
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 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;
|
||||||
|
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);
|
||||||
|
drawhighlight(tmp_select);
|
||||||
|
}
|
||||||
|
|
||||||
drawSelectMenu();
|
drawSelectMenu();
|
||||||
PrintAllNetworkLinks();
|
PrintAllNetworkLinks();
|
||||||
@ -108,14 +191,14 @@ function PrintScreen(WhatPassedIn=-1)
|
|||||||
else if(what == 1) //PuzzleDescription/Info
|
else if(what == 1) //PuzzleDescription/Info
|
||||||
{
|
{
|
||||||
//Display the text about the puzzle
|
//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
|
else if(what == 2) //PuzzleSelect
|
||||||
{
|
{
|
||||||
//TextMenuSelection
|
//TextMenuSelection
|
||||||
PrintPuzzleSelectMenu(0);
|
PrintPuzzleSelectMenu(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTouchStart(evt)
|
function handleTouchStart(evt)
|
||||||
@ -150,6 +233,82 @@ function handleMouseDown(evt)
|
|||||||
if(uiMode==0) SelectMenu_handleMouseDown(mouseDownLocation);
|
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)
|
function handleMouseUp(evt)
|
||||||
{
|
{
|
||||||
//evt.preventDefault();
|
//evt.preventDefault();
|
||||||
@ -169,25 +328,17 @@ function handleMouseUp(evt)
|
|||||||
}
|
}
|
||||||
if(!mouseDidMovement)
|
if(!mouseDidMovement)
|
||||||
{ //If we are not dragging, it is a click
|
{ //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);
|
if(uiMode==1) TextWindow_handleMouseUp(evt);
|
||||||
else if (uiMode == 2) TextWindow_handleMouseUp(evt);
|
else if (uiMode == 2) TextWindow_handleMouseUp(evt);
|
||||||
else if(uiMode==0 && evt.pageX >= MainCanvas.width - small_button_size)
|
if (needsrefresh) {
|
||||||
{
|
if (ui_selectRect == null) setStatus(""); //we clicked on nothing
|
||||||
console.log("clicked far enough x wise");
|
|
||||||
//We may be clicking on one of the small buttons
|
|
||||||
if(evt.pageY < small_button_size)
|
|
||||||
{
|
|
||||||
//We clicked on the puzzle-select menu
|
|
||||||
console.log("PuzzleSelect pressed");
|
|
||||||
uiMode=2;
|
|
||||||
PrintScreen();
|
PrintScreen();
|
||||||
} else if(evt.pageY < small_button_size *2)
|
|
||||||
{
|
|
||||||
console.log("Selected info button");
|
|
||||||
//It is the info button
|
|
||||||
uiMode=1;
|
|
||||||
PrintScreen();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +346,40 @@ function handleMouseUp(evt)
|
|||||||
mouseDidMovement=false; //reset it after we raise the button
|
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)
|
function handleMouseMove(evt)
|
||||||
{
|
{
|
||||||
@ -216,12 +401,30 @@ function handleMouseMove(evt)
|
|||||||
}
|
}
|
||||||
else //Mouse is not down. Not dragging
|
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)
|
if(uiMode==2)
|
||||||
{
|
{
|
||||||
textMenu_HandleMouseMove(evt);
|
textMenu_HandleMouseMove(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyLocation({ pageX, pageY }) {
|
function copyLocation({ pageX, pageY }) {
|
||||||
@ -244,6 +447,11 @@ function PrintNetworkLink(linkToPrint)
|
|||||||
var spoint = convertXYPointToActual(newPointFromString(sdevice.location));
|
var spoint = convertXYPointToActual(newPointFromString(sdevice.location));
|
||||||
var dpoint = convertXYPointToActual(newPointFromString(ddevice.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
|
//Now we draw a line between them
|
||||||
MainCanvas_ctx.beginPath();
|
MainCanvas_ctx.beginPath();
|
||||||
MainCanvas_ctx.moveTo(spoint.x,spoint.y);
|
MainCanvas_ctx.moveTo(spoint.x,spoint.y);
|
||||||
@ -252,6 +460,7 @@ function PrintNetworkLink(linkToPrint)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function PrintAllNetworkLinks()
|
function PrintAllNetworkLinks()
|
||||||
@ -270,15 +479,87 @@ function PrintAllNetworkLinks()
|
|||||||
|
|
||||||
function PrintNetworkDevice(ToPrint)
|
function PrintNetworkDevice(ToPrint)
|
||||||
{
|
{
|
||||||
//We should have passed in a working link, make sure it exists
|
//We should have passed in a working device, make sure it exists
|
||||||
if(ToPrint !== null)
|
if(ToPrint !== null)
|
||||||
{
|
{
|
||||||
var rect = deviceRectangle(ToPrint);
|
var rect = deviceRectangle(ToPrint);
|
||||||
|
var actionrect = makeRectangle(rect.spoint.x, rect.spoint.y, rect.width, rect.height);
|
||||||
|
|
||||||
var dname = ToPrint.mytype;
|
var dname = ToPrint.mytype;
|
||||||
if(dname=="net_switch") dname="switch";
|
if(dname=="net_switch") dname="switch";
|
||||||
if(dname=="net_hub") dname="hub";
|
if(dname=="net_hub") dname="hub";
|
||||||
//console.log("printing device " + dname);
|
//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);
|
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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,6 +574,50 @@ function PrintAllNetworkDevices()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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)
|
function convertXYPointToActual(point)
|
||||||
{
|
{
|
||||||
//We have an x and y coordinate which needs to be converted to the canvas size
|
//We have an x and y coordinate which needs to be converted to the canvas size
|
||||||
@ -335,7 +660,269 @@ function deviceRectangle(theDevice)
|
|||||||
spoint : newPointFromPair(centerpoint.x-delta, centerpoint.y-delta),
|
spoint : newPointFromPair(centerpoint.x-delta, centerpoint.y-delta),
|
||||||
height : imageSize,
|
height : imageSize,
|
||||||
width : imageSize,
|
width : imageSize,
|
||||||
epoint : newPointFromPair(centerpoint.x+delta, centerpoint.y+delta)
|
epoint : newPointFromPair(centerpoint.x + delta, centerpoint.y + delta),
|
||||||
|
center: centerpoint,
|
||||||
}
|
}
|
||||||
return rect;
|
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++;
|
||||||
|
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++) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user