From 14694cdfa61b0d8fcec4d1cb80bf10b265308f90 Mon Sep 17 00:00:00 2001 From: CodedSakura Date: Tue, 7 Jul 2026 21:56:30 +0300 Subject: [PATCH] begin implementing tooltips proper --- scripts/dom-list.js | 3 ++ scripts/main.js | 8 ++--- scripts/planner.js | 9 +++-- scripts/tooltip.js | 84 +++++++++++++++++++++++++++++++++++++++++++++ style.css | 18 ++++++++++ 5 files changed, 116 insertions(+), 6 deletions(-) diff --git a/scripts/dom-list.js b/scripts/dom-list.js index 6b49040..3e3389c 100644 --- a/scripts/dom-list.js +++ b/scripts/dom-list.js @@ -1,3 +1,5 @@ +import { deleteTooltip } from "./tooltip.js"; + export class DomList { list; template; @@ -8,6 +10,7 @@ export class DomList { } clear() { + this.list.querySelectorAll("[data-tooltip]").forEach(e => deleteTooltip(Number(e.dataset.tooltip))) this.list.replaceChildren(...this.list.querySelectorAll("template, [data-keep]")); } diff --git a/scripts/main.js b/scripts/main.js index 9dcd010..8f3d48f 100644 --- a/scripts/main.js +++ b/scripts/main.js @@ -1,11 +1,10 @@ -import { atlasMetadata, makeAtlasImage } from "./atlas.js"; -import { DomList } from "./dom-list.js"; +import { loadConfiguration } from "./configuration.js"; import { addEventToButton, addEventToInput, debounce, getElements } from "./dom-utils.js"; import { emitEvent, listenTo } from "./events.js"; -import { loadConfiguration } from "./configuration.js"; -import { getState, setState, STATE } from "./state.js"; import { initializePlanner } from "./planner.js"; import { initializeMenuResizing } from "./resize-menus.js"; +import { getState, setState, STATE } from "./state.js"; +import { initializeTooltips } from "./tooltip.js"; window.addEventListener("load", () => { emitEvent("setup-start"); @@ -37,6 +36,7 @@ window.addEventListener("load", () => { initializePlanner(); initializeMenuResizing(); + initializeTooltips(); emitEvent("setup-end"); diff --git a/scripts/planner.js b/scripts/planner.js index 6f2be54..f3a4291 100644 --- a/scripts/planner.js +++ b/scripts/planner.js @@ -2,6 +2,7 @@ import {atlasMetadata, makeAtlasImage} from "./atlas.js"; import {DomList} from "./dom-list.js"; import { emitEvent, listenTo } from "./events.js"; import { Filter } from "./filter.js"; +import { createTooltip } from "./tooltip.js"; let suppressHover = false; let multiblockSize = [7, 7, 5]; // width (screen x), depth (screen y), height (xy grids) @@ -98,7 +99,7 @@ function listClickEvent(e) { const items = document.querySelectorAll("#block-list [data-index]"); items.forEach(i => delete i.dataset.active); activeItem = Number(e.currentTarget.dataset.index); - e.currentTarget.dataset.active = undefined; + e.currentTarget.dataset.active = ""; } export function initializePlanner() { @@ -121,6 +122,11 @@ function buildBlockPicker() { atlasMetadata.forEach((m, i) => { const item = grid.makeItem(); item.dataset.index = i.toString(10); + console.log(m); + item.dataset.tooltip = createTooltip([ + m.modules["plannerator:display_name"].display_name, + + ]).toString(10); if (!filter.test(m.modules["plannerator:display_name"].display_name)) { item.classList.add("hidden"); } @@ -132,7 +138,6 @@ function buildBlockPicker() { function buildPlanner() { document.addEventListener("keydown", e => { - console.log(e); if (e.key === "H") { suppressHover = !suppressHover; } diff --git a/scripts/tooltip.js b/scripts/tooltip.js index e69de29..688ac98 100644 --- a/scripts/tooltip.js +++ b/scripts/tooltip.js @@ -0,0 +1,84 @@ +import { debounce } from "./dom-utils.js"; +import { emitEvent, listenTo } from "./events.js"; + +const tooltips = {}; +let tooltipsCounter = 0; +let lastTarget = null; +let suppressTooltips = false; + +export function initializeTooltips() { + window.addEventListener("mousemove", () => { + if (lastTarget !== null) { + emitEvent("tooltips:hide"); + } + lastTarget = null; + }); + window.addEventListener("mousemove", debounce(e => { + lastTarget = e.target; + emitEvent("tooltips:show"); + }, 500)); + + listenTo("tooltips:show", showTooltip); + listenTo("tooltips:hide", hideTooltip); + + document.addEventListener("keydown", e => { + if (e.key === "T") { + suppressTooltips = !suppressTooltips; + } + }); +} + +export function createTooltip(data) { + const id = tooltipsCounter; + tooltips[id] = data; + tooltipsCounter++; + return id; +} + +export function getTooltip(id) { + return tooltips[id]; +} + +export function deleteTooltip(id) { + delete tooltips[id]; +} + +function showTooltip() { + if (suppressTooltips) return; + if (!lastTarget.dataset.tooltip) return; + + const dom = createTooltipDom(lastTarget.dataset.tooltip); + if (!dom) return; + + lastTarget.appendChild(dom); +} +function hideTooltip() { + if (suppressTooltips) return; + if (!lastTarget.dataset.tooltip) return; + + console.log(lastTarget.querySelector(".tooltip")) + lastTarget.removeChild(lastTarget.querySelector(".tooltip")); +} + +function createTooltipDom(id) { + const data = tooltips[id]; + if (!Array.isArray(data)) { + console.warn("tooltip %s is not an array: %o", id, data); + return null; + } + const div = document.createElement("div"); + div.classList.add("tooltip"); + for (const row of data) { + const rowElem = document.createElement("div"); + + if (typeof row === "string") { + rowElem.innerText = row; + } else { + // TODO: support rich tooltips + throw row; + } + + div.appendChild(rowElem); + } + return div; +} diff --git a/style.css b/style.css index ba242d3..ada788d 100644 --- a/style.css +++ b/style.css @@ -211,3 +211,21 @@ input:not([type="checkbox"]):not([type="radio"]):not([type="file"]) { #block-list [data-active] { outline: calc(var(--scale-factor) * 1px) solid var(--block-active-outline-color, #000); } +#block-list [data-index]:hover:not([data-active]) { + outline: calc(var(--scale-factor) * 1px) solid var(--block-hover-outline-color, #6666); +} + +[data-tooltip] { + position: relative; +} +[data-tooltip] > .tooltip { + position: fixed; + z-index: 10; + background: var(--tooltip-background, #222d); + color: var(--tooltip-foreground, #fff); + font-size: var(--tooltip-font-size, .8em); + /*border-radius: var(--tooltip-border-radius, 0.25em);*/ + padding: var(--tooltip-padding, 0.25em); + border: var(--tooltip-border-size, 1px) solid var(--tooltip-border-color, #fff); + /*max-width: var(--tooltip-width, 200px);*/ +}