EduNetworkBuilder/Web/textwindow.js

225 lines
7.5 KiB
JavaScript
Raw Normal View History

//This file pertains to the textwindow.
//We use this for displaying a puzzle's starting instructions
//and for choosing new puzzles.
var tmOutsideYMargin=20; //How far from the top and bottom left blank
var tmOutsideXMargin=20; //How far from right and left side left blank
var tmBorderWidth=4;
var tmMenuBarHight=20;
var tmScrollBarWidth=20;
var tmWindowBackground="grey";
var tmTextHeight; //Calculated when we build the page
var tmLastHighlightedIndex=-1;
var tmTextYGap=5; //The gap between lines
var tmPuzzleSelectMenuLevel=0;
var cachedTextMenuCanvas = null;
//Print the textmenu
2024-04-19 18:02:46 +02:00
function textMenuPrint(TextToPrint, selectedindex = -1, highlightedindex = -1)
{
//It would be nice to print it on top of whatever is currently there.
//But we will do that later.
PrintScreen(0); //Print the network, then we can lay over it
if(cachedTextMenuCanvas == null)
{
cachedTextMenuCanvas = document.createElement('canvas');
cachedTextMenuCanvas.width = MainCanvas.width - (tmOutsideXMargin * 2);
cachedTextMenuCanvas.height = MainCanvas.height - (tmOutsideYMargin * 2);
}
//If we get here, it is already created. Get the context
var cTMCctx = cachedTextMenuCanvas.getContext('2d');
var rect;
//Fill in the background
cTMCctx.fillStyle = tmWindowBackground;
cTMCctx.fillRect(0,0, cachedTextMenuCanvas.width, cachedTextMenuCanvas.height);
//Put the X there so we can click on it
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
cTMCctx.drawImage(imageFromName("ArrowUp"),cachedTextMenuCanvas.width - tmScrollBarWidth,tmMenuBarHight,tmScrollBarWidth,tmMenuBarHight);
//Put the X 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();
2024-04-19 18:02:46 +02:00
var cachedTextMenuTextCanvas = document.createElement('canvas');
//Figure out how much space we need. - start with a simple canvas (non expandable)
cachedTextMenuTextCanvas.width = cachedTextMenuCanvas.width - tmScrollBarWidth;
cachedTextMenuTextCanvas.height = cachedTextMenuCanvas.height;
var cTMTCctx = cachedTextMenuTextCanvas.getContext('2d');
cTMTCctx.strokeStyle="black";
cTMTCctx.font = "20px serif";
var lines = [];
if(typeof(TextToPrint) === "string")
lines = fragmentTextIntoLines(cTMTCctx, TextToPrint, cachedTextMenuTextCanvas.width - 10);
else
lines = TextToPrint; //If we passed in a list of strings
//Now we have the number of lines.
var metrics = cTMTCctx.measureText("test");
var yHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent + tmTextYGap; //the hight of the default font and gap
tmTextHeight = yHeight; //store it for use in highlighting
2024-04-19 18:02:46 +02:00
//console.log("Height = "+yHeight);
var totalHeight = (lines.length * yHeight) + tmTextYGap;
if(cachedTextMenuTextCanvas.height < totalHeight) cachedTextMenuTextCanvas.height = totalHeight;// resize if needed
2024-04-19 18:02:46 +02:00
//Highlight text
if (highlightedindex >= 0)
{
//console.log("Showing hilighted index " + highlightedindex);
//Fill in the area highlighted
cTMTCctx.fillStyle = "white";
cTMTCctx.globalAlpha = 0.3; //mostly transparent
cTMTCctx.fillRect(0,highlightedindex * yHeight + (yHeight/3), cachedTextMenuCanvas.width, yHeight);
cTMTCctx.globalAlpha = 1.0; //reset
}
//Chosen text
if (selectedindex >= 0)
{
//console.log("Showing selected index " + selectedindex + " " + yHeight);
//Fill in the area highlighted
cTMTCctx.fillStyle = "green";
cTMTCctx.globalAlpha = 0.4; //mostly transparent
cTMTCctx.fillRect(0,selectedindex * yHeight + (yHeight/3), cachedTextMenuCanvas.width, yHeight);
cTMTCctx.globalAlpha = 1.0; //reset
}
cTMTCctx.fillStyle = "black";
cTMTCctx.strokeStyle="black";
//Now, print text on the canvas.
for (var i = 0; i < lines.length; i++)
{
cTMTCctx.fillText(lines[i], 5, ((i+1) * yHeight));
//console.log("printing text part: " + lines[i]);
}
//Write the text canvas on the main canvas. If we are scrolled up or down, do that.
cTMCctx.drawImage(cachedTextMenuTextCanvas,0,0);
//create and Draw the scroll-bar on the side
//Then make the text if we have not done so
//Finally print on top of the main canvas
MainCanvas_ctx.globalAlpha = 0.9; //some transparancy
MainCanvas_ctx.drawImage(cachedTextMenuCanvas,tmOutsideXMargin, tmOutsideYMargin)
MainCanvas_ctx.globalAlpha = 1; //reset transparancy
}
function fragmentTextIntoLines(ctx, text, maxWidth) {
var words = text.split(" ");
var lines = [];
var currentLine = words[0];
for (var i = 1; i < words.length; i++) {
var word = words[i];
var width = ctx.measureText(currentLine + " " + word).width;
if (width < maxWidth) {
currentLine += " " + word;
} else {
lines.push(currentLine);
currentLine = word;
}
}
lines.push(currentLine);
return lines;
}
function TextWindow_handleMouseUp(evt)
{
console.log("TextWindow Mouse Up");
//If we get here, it is a mouse-click event. See if we are on the X
2024-04-19 18:02:46 +02:00
if(mouseDownLocation.pageX + tmScrollBarWidth >= cachedTextMenuCanvas.width - tmScrollBarWidth)
{
console.log("TextWindow Mouse Up - X fits");
//The X fits. Now, see which button, or scroll-bar we clicked on.
2024-04-19 18:02:46 +02:00
if(mouseDownLocation.pageY - tmOutsideYMargin <= tmMenuBarHight
&& mouseDownLocation.pageY - tmOutsideYMargin >= 0)
{
console.log("TextWindow Mouse Up - Y fits");
//We clicked the X
textwindow_XClick();
}
}
else
{
if(uiMode == 2)
{
//We are in puzzle-select mode and clicked somewhere.
var levellist=networkNamesMatchingText("Level"+tmPuzzleSelectMenuLevel);
if(tmLastHighlightedIndex>=0 && tmLastHighlightedIndex< levellist.length)
{
//We found a puzzle
console.log("Clicked on puzzle: " + levellist[tmLastHighlightedIndex]);
uiMode=1;
switchPuzzle(levellist[tmLastHighlightedIndex]);
}
}
}
mouseDidMovement=false; //reset it after we raise the button
2024-04-19 18:02:46 +02:00
}
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();
}
2024-04-19 18:02:46 +02:00
function PrintPuzzleSelectMenu(level=0)
{
var levellist=networkNamesMatchingText("Level"+level);
//console.log("list is this long: " + levellist.length);
textMenuPrint(levellist, -1, tmLastHighlightedIndex);
tmPuzzleSelectMenuLevel=level;
}
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);
}
}