diff options
author | 0neGal <mail@0negal.com> | 2023-05-07 00:52:39 +0200 |
---|---|---|
committer | 0neGal <mail@0negal.com> | 2023-05-07 00:59:38 +0200 |
commit | 0d7293cd5cdacd9c46bb637e367e969606031038 (patch) | |
tree | 91d6974fa5c3671f5cca4b7db98ee2f3f3d93ccf | |
parent | cfec36cbdf00b181e6560be15c6b341842894e00 (diff) | |
download | Viper-0d7293cd5cdacd9c46bb637e367e969606031038.tar.gz Viper-0d7293cd5cdacd9c46bb637e367e969606031038.zip |
added hover tooltips
They're pretty simple to use, and automatically make themselves fit on
screen, on top of automatically disappearing and appearing of course.
I've used them a few places now, and not sure where else they can be
used, there are of course localization strings that need, well,
localization, and I'll create a PR for this on a later date.
-rw-r--r-- | src/app/css/tooltip.css | 21 | ||||
-rw-r--r-- | src/app/index.html | 15 | ||||
-rw-r--r-- | src/app/js/tooltip.js | 130 | ||||
-rw-r--r-- | src/app/main.css | 1 | ||||
-rw-r--r-- | src/lang/en.json | 9 |
5 files changed, 169 insertions, 7 deletions
diff --git a/src/app/css/tooltip.css b/src/app/css/tooltip.css new file mode 100644 index 0000000..673cc64 --- /dev/null +++ b/src/app/css/tooltip.css @@ -0,0 +1,21 @@ +@import "theming.css"; + +#tooltip { + color: white; + opacity: 0.0; + position: fixed; + font-weight: 600; + font-size: 0.8em; + width: max-content; + z-index: 99999999999; + pointer-events: none; + background: var(--bg); + backdrop-filter: blur(15px); + transition: opacity 0.15s ease-in-out; + border-radius: calc(var(--padding) / 1); + padding: calc(var(--padding) / 2.8) calc(var(--padding) / 1.8); +} + +#tooltip.visible { + opacity: 1.0; +} diff --git a/src/app/index.html b/src/app/index.html index 52ac532..2b2abd1 100644 --- a/src/app/index.html +++ b/src/app/index.html @@ -6,13 +6,15 @@ <meta charset="utf-8"> </head> <body> + <div id="tooltip">Test</div> + <div id="bgHolder"></div> <div id="toasts"></div> <div id="winbtns"> - <div id="settings" onclick="Settings.toggle(true)"></div> - <div id="minimize" onclick="ipcRenderer.send('minimize')"></div> - <div id="close" onclick="ipcRenderer.send('exit')"></div> + <div id="settings" tooltip="%%tooltip.settings%%" onclick="Settings.toggle(true)"></div> + <div id="minimize" tooltip="%%tooltip.minimize%%" onclick="ipcRenderer.send('minimize')"></div> + <div id="close" tooltip="%%tooltip.close%%" onclick="ipcRenderer.send('exit')"></div> </div> <div id="dragUI"> @@ -170,9 +172,9 @@ </div> <nav class="gamesContainer"> - <button id="vpBtn" onclick="page(0)"></button> - <button id="nsBtn" onclick="page(1)"></button> - <button id="tfBtn" onclick="page(2)"></button> + <button id="vpBtn" tooltip="%%tooltip.pages.viper%%" tooltip-position="horizontal" onclick="page(0)"></button> + <button id="nsBtn" tooltip="%%tooltip.pages.northstar%%" tooltip-position="horizontal" onclick="page(1)"></button> + <button id="tfBtn" tooltip="%%tooltip.pages.titanfall%%" tooltip-position="horizontal" onclick="page(2)"></button> </nav> <div class="mainContainer"> @@ -261,6 +263,7 @@ <script src="js/misc.js"></script> <script src="js/mods.js"></script> <script src="js/toast.js"></script> + <script src="js/tooltip.js"></script> <script src="js/browser.js"></script> <script src="js/settings.js"></script> <script src="js/launcher.js"></script> diff --git a/src/app/js/tooltip.js b/src/app/js/tooltip.js new file mode 100644 index 0000000..13dcd67 --- /dev/null +++ b/src/app/js/tooltip.js @@ -0,0 +1,130 @@ +var tooltip = { + target: false, + div: document.getElementById("tooltip"), +} + +tooltip.show = (target, text, vertical_positioned) => { + if (target == tooltip.target) { + return; + } + + tooltip.target = target; + + let div = tooltip.div; + + let padding = parseFloat( + getComputedStyle(div).getPropertyValue("padding") + ); + + let tooltip_padding = padding / 1.2; + + let get_positions = () => { + div.innerHTML = text; + + let div_rect = div.getBoundingClientRect(); + let target_rect = target.getBoundingClientRect(); + + let x_pos = 0; + let y_pos = 0; + + if (vertical_positioned) { + x_pos = target_rect.x + (target_rect.width / 2); + x_pos = x_pos - (div_rect.width / 2); + + if (x_pos < padding) { + x_pos = padding; + } else if (x_pos + div_rect.width > window.innerWidth - padding) { + x_pos = window.innerWidth - div_rect.width - padding; + } + + y_pos = target_rect.y + target_rect.height + tooltip_padding; + + if (y_pos + div_rect.height > window.innerHeight) { + y_pos = target_rect.y - div_rect.height - tooltip_padding; + } + } else { + x_pos = target_rect.x - div_rect.width - tooltip_padding; + + if (x_pos < 0) { + x_pos = target_rect.x + target_rect.width + tooltip_padding; + } + + if (x_pos > window.innerWidth - padding) { + x_pos = window.innerWidth - div_rect.width - padding; + } + + y_pos = target_rect.y + (target_rect.height / 2); + y_pos = y_pos - (div_rect.height / 2); + } + + return {x: x_pos, y: y_pos} + } + + let transition_duration = parseFloat( + getComputedStyle(div).getPropertyValue("transition-duration") + ) * 1000; + + if (div.classList.contains("visible")) { + div.classList.remove("visible"); + } + + return new Promise((resolve) => { + setTimeout(() => { + if (tooltip.target != target) { + return resolve(); + } + + let pos = get_positions(); + div.style.top = pos.y + "px"; + div.style.left = pos.x + "px"; + }, transition_duration) + + setTimeout(() => { + if (tooltip.target != target) { + return resolve(); + } + + div.classList.add("visible"); + + resolve(); + }, transition_duration * 2) + }) +} + +let mouse_y = 0; +let mouse_x = 0; + +let tooltip_event = (event) => { + if (event && event.x && event.y) { + mouse_y = event.y; + mouse_x = event.x; + } else { + event = { + x: mouse_x, + y: mouse_y + } + } + + let at_mouse = document.elementFromPoint(event.x, event.y); + + if (! at_mouse) {return} + + let tooltip_text = at_mouse.getAttribute("tooltip"); + if (! tooltip_text) { + tooltip.target = false; + tooltip.div.classList.remove("visible"); + + return; + } + + let position = at_mouse.getAttribute("tooltip-position") || "vertical"; + tooltip.show(at_mouse, tooltip_text, (position == "vertical")); +} + +setInterval(tooltip_event, 1000); +document.addEventListener("click", tooltip_event); +document.addEventListener("mouseup", tooltip_event); +document.addEventListener("mousedown", tooltip_event); +document.addEventListener("mousemove", tooltip_event); +document.addEventListener("mouseenter", tooltip_event); +document.addEventListener("mouseleave", tooltip_event); diff --git a/src/app/main.css b/src/app/main.css index d76afdf..fa2fff2 100644 --- a/src/app/main.css +++ b/src/app/main.css @@ -2,6 +2,7 @@ @import "css/dragui.css"; @import "css/toasts.css"; @import "css/popups.css"; +@import "css/tooltip.css"; @import "css/theming.css"; @import "css/launcher.css"; diff --git a/src/lang/en.json b/src/lang/en.json index 4f90f32..bd95a53 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -169,5 +169,12 @@ "general.invalidconfig": "Your config file is improperly formatted, if it's been manually edited, please validate that everything is typed correctly.\n\nIf you did not manually edit the config file, it is recommended to simply reset the config.\n\nTo reset your config file simply click \"Ok\" below.\n\nMore details:\n", "request.viper.noReleaseNotes": "Couldn't fetch Viper release notes.\nTry again later!", - "request.northstar.noReleaseNotes": "Couldn't fetch Northstar release notes.\nTry again later!" + "request.northstar.noReleaseNotes": "Couldn't fetch Northstar release notes.\nTry again later!", + + "tooltip.close": "Closes Viper", + "tooltip.minimize": "Minimizes the window", + "tooltip.settings": "Opens the settings popup", + "tooltip.pages.viper": "Viper", + "tooltip.pages.northstar": "Northstar", + "tooltip.pages.titanfall": "Titanfall 2" } |