add planner tooltip autogen support

This commit is contained in:
CodedSakura 2026-07-21 16:24:20 +02:00
parent 4d6c0f990d
commit f80bebe9de
4 changed files with 65 additions and 17 deletions

View File

@ -85,7 +85,7 @@
</label> </label>
</div> </div>
</header> </header>
<div class="list" id="planner" data-retain-tooltip-hover> <div class="list" id="planner">
<template> <template>
<div class="grid m2"> <div class="grid m2">
<template> <template>
@ -124,7 +124,7 @@
</section> </section>
</aside> </aside>
<footer> <footer>
<div>pre-alpha 1.2</div> <div>pre-alpha 1.3</div>
<div> <div>
<a href="https://discord.gg/Eq72HwPqfg">Discord server</a> <a href="https://discord.gg/Eq72HwPqfg">Discord server</a>
</div> </div>
@ -144,7 +144,6 @@
Roadmap: Roadmap:
</p> </p>
<ul> <ul>
<li>Reactor tooltips</li>
<li>Reactor verification and stats</li> <li>Reactor verification and stats</li>
<li>Casing improvements</li> <li>Casing improvements</li>
<li>Keyboard shortcuts</li> <li>Keyboard shortcuts</li>

View File

@ -1,4 +1,4 @@
import { makeAtlasImage } from "./atlas.js"; import { getAtlasIndexFromMetadata, getAtlasMetadata, makeAtlasImage } from "./atlas.js";
import { DomList } from "./dom-list.js"; import { DomList } from "./dom-list.js";
import { getElements } from "./dom-utils.js"; import { getElements } from "./dom-utils.js";
import { emitEvent, listenTo } from "./events.js"; import { emitEvent, listenTo } from "./events.js";
@ -6,7 +6,9 @@ import { initialize3dArray } from "./js-utils.js";
import { recall, save } from "./storage.js"; import { recall, save } from "./storage.js";
import { registerLoadCallback } from "./main.js"; import { registerLoadCallback } from "./main.js";
import { getBlockPickerActiveItem, getBlockPickerRecipe } from "./block-picker.js"; import { getBlockPickerActiveItem, getBlockPickerRecipe } from "./block-picker.js";
import { deleteSolverMetadata, setSolverMetadata } from "./solver.js"; import { deleteSolverMetadata, getSolverMetadata, setSolverMetadata } from "./solver.js";
import { retainTooltipHover } from "./tooltip.js";
import { checkEquivalence, findFullEntry, findFullEntryAnywhere, lookupFromMetadata } from "./ncpf-utils.js";
const zoomOptions = [ 0.5, 1, 2, 3, 4, 5 ]; const zoomOptions = [ 0.5, 1, 2, 3, 4, 5 ];
const zoomDefault = 2; const zoomDefault = 2;
@ -110,6 +112,7 @@ function buildPlanner(textures) {
if (y === 0 || y === multiblockSize[1] - 1) { if (y === 0 || y === multiblockSize[1] - 1) {
item.dataset.casing = ""; item.dataset.casing = "";
} }
item.addEventListener("mousemove", retainTooltipHover);
const grid = new DomList(item); const grid = new DomList(item);
grid.clear(); grid.clear();
for (let z = 0; z < multiblockSize[2]; z++) { for (let z = 0; z < multiblockSize[2]; z++) {
@ -128,6 +131,7 @@ function buildPlanner(textures) {
|| z === 0 || z === multiblockSize[2] - 1) { || z === 0 || z === multiblockSize[2] - 1) {
cell.dataset.casing = ""; cell.dataset.casing = "";
} }
cell.dataset.tooltip = "auto";
cell.appendChild(makeAtlasImage(texture)); cell.appendChild(makeAtlasImage(texture));
cell.addEventListener("mouseenter", cellHoverEvent); cell.addEventListener("mouseenter", cellHoverEvent);
cell.addEventListener("mouseleave", cellHoverEvent); cell.addEventListener("mouseleave", cellHoverEvent);
@ -307,3 +311,31 @@ export function getPlannerCellDom(x, y, z) {
export const getPlannerMultiblockType = () => multiblockType; export const getPlannerMultiblockType = () => multiblockType;
export const getPlannerMultiblockSize = () => multiblockSize; export const getPlannerMultiblockSize = () => multiblockSize;
export function* getCellTooltip(cell) {
if (cell.dataset.tile === "-1") {
return;
}
const metadata = getAtlasMetadata(cell.dataset.tile)
const data = lookupFromMetadata(metadata);
const solverMetadata = getSolverMetadata(cell);
yield data.modules["plannerator:display_name"].display_name;
if (solverMetadata) {
if (solverMetadata.block_recipe) {
const recipeList = data.modules["ncpf:block_recipes"].recipes;
const recipe = recipeList.find(r => checkEquivalence(r, solverMetadata.block_recipe));
yield {
type: "item",
name: recipe.modules["plannerator:display_name"].display_name,
atlasIndex: getAtlasIndexFromMetadata(recipe, multiblockType, "ncpf:block_recipes"),
}
}
}
yield {
type: "italics",
text: metadata.configurationAddon.name,
};
}

View File

@ -2,6 +2,8 @@ import { debounce } from "./dom-utils.js";
import { emitEvent, listenTo } from "./events.js"; import { emitEvent, listenTo } from "./events.js";
import { registerLoadCallback } from "./main.js"; import { registerLoadCallback } from "./main.js";
import { makeAtlasImage } from "./atlas.js"; import { makeAtlasImage } from "./atlas.js";
import { DevError } from "./errors.js";
import { getCellTooltip } from "./planner.js";
const tooltips = {}; const tooltips = {};
let tooltipsCounter = 0; let tooltipsCounter = 0;
@ -11,13 +13,7 @@ let activeTooltipTarget = null;
registerLoadCallback(() => { registerLoadCallback(() => {
document.querySelectorAll("[data-retain-tooltip-hover]").forEach(elem => document.querySelectorAll("[data-retain-tooltip-hover]").forEach(elem =>
elem.addEventListener("mousemove", e => { elem.addEventListener("mousemove", retainTooltipHover));
if (lastCoordinates !== null) {
e.stopPropagation();
lastCoordinates = { x: e.pageX, y: e.pageY };
emitEvent("tooltips:show");
}
}));
window.addEventListener("mousemove", () => { window.addEventListener("mousemove", () => {
if (lastCoordinates !== null) { if (lastCoordinates !== null) {
emitEvent("tooltips:hide"); emitEvent("tooltips:hide");
@ -43,6 +39,14 @@ registerLoadCallback(() => {
}); });
}); });
export function retainTooltipHover(e) {
if (lastCoordinates !== null) {
e.stopPropagation();
lastCoordinates = { x: e.pageX, y: e.pageY };
emitEvent("tooltips:show");
}
}
export function createTooltip(data) { export function createTooltip(data) {
const id = tooltipsCounter; const id = tooltipsCounter;
tooltips[id] = data; tooltips[id] = data;
@ -86,7 +90,6 @@ export function positionAsTooltip(mainElement, tooltipElement, { horizontal = "l
function showTooltip() { function showTooltip() {
if (suppressTooltips) return; if (suppressTooltips) return;
if (!lastCoordinates) return; if (!lastCoordinates) return;
if (activeTooltipTarget) hideTooltip();
let target = document.elementFromPoint(lastCoordinates.x, lastCoordinates.y); let target = document.elementFromPoint(lastCoordinates.x, lastCoordinates.y);
while (target && !target.dataset.tooltip) { while (target && !target.dataset.tooltip) {
@ -94,7 +97,12 @@ function showTooltip() {
} }
if (!target) return; if (!target) return;
const dom = createTooltipDom(target.dataset.tooltip); if (!target.isSameNode(activeTooltipTarget)) hideTooltip();
else return;
const dom = target.dataset.tooltip === "auto"
? createAutoTooltipDom(target)
: createTooltipDom(tooltips[target.dataset.tooltip]);
if (!dom) return; if (!dom) return;
const targetRect = target.getBoundingClientRect(); const targetRect = target.getBoundingClientRect();
@ -117,10 +125,11 @@ function hideTooltip() {
activeTooltipTarget = null; activeTooltipTarget = null;
} }
function createTooltipDom(id) { function createTooltipDom(data) {
const data = tooltips[id];
if (!Array.isArray(data)) { if (!Array.isArray(data)) {
console.warn("tooltip %s is not an array: %o", id, data); throw new DevError(`tooltip is not an array: ${data}`);
}
if (data.length === 0) {
return null; return null;
} }
const div = document.createElement("div"); const div = document.createElement("div");
@ -164,6 +173,13 @@ function createTooltipDom(id) {
return div; return div;
} }
function createAutoTooltipDom(element) {
if (element.dataset.x && element.dataset.tile) {
return createTooltipDom([...getCellTooltip(element)]);
}
throw new DevError(`unknown element for auto tooltip: ${element}`);
}
export function tooltipDataToPlain(data) { export function tooltipDataToPlain(data) {
if (!Array.isArray(data)) { if (!Array.isArray(data)) {
console.warn("tooltip data is not an array: %o", data); console.warn("tooltip data is not an array: %o", data);

View File

@ -332,6 +332,7 @@ input:not([type="checkbox"]):not([type="radio"]):not([type="file"]) {
padding: var(--tooltip-padding, 0.25em); padding: var(--tooltip-padding, 0.25em);
border: var(--tooltip-border-size, 1px) solid var(--tooltip-border-color, #fff); border: var(--tooltip-border-size, 1px) solid var(--tooltip-border-color, #fff);
/*max-width: var(--tooltip-width, 200px);*/ /*max-width: var(--tooltip-width, 200px);*/
pointer-events: none;
} }
.tooltip > .tooltip--item { .tooltip > .tooltip--item {
display: flex; display: flex;