From 858bfef1bbf704fc8f87a6e991fa9e36a3736cc5 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Fri, 14 Jun 2024 16:01:41 -0500 Subject: [PATCH] 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. --- Web/textwindow.js | 202 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 193 insertions(+), 9 deletions(-) diff --git a/Web/textwindow.js b/Web/textwindow.js index e639902..5044603 100644 --- a/Web/textwindow.js +++ b/Web/textwindow.js @@ -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); } \ No newline at end of file