From 56eadcb0df2b0d11acbe93de0105fee3f0c95ef8 Mon Sep 17 00:00:00 2001 From: Aylong <69762909+AyIong@users.noreply.github.com> Date: Mon, 29 Jul 2024 21:55:22 +0300 Subject: [PATCH] Refactor Stat Panel styles and more TGUI-like appearance (#85257) ## About The Pull Request The PR came out a little bigger than I had planned, but creating separate ones for a couple of little things seemed unnecessary to me. Let me start with the most important thing: Stat Panel now scales like TGchat and also looks closer to TGUI! By default, the Stat Panel font size is tied to the chat font size, but this can be changed in a couple of clicks... The rest of the changes are not as big: 1. Stat Panel styles are now more organised 2. The way themes are applied to Byond Skin has been refactored, if someone decides to make a new theme (maybe me), it won't be necessary to copy all the elements 3. NumberInput into the general chat settings tab, was changed to slider 4. Reoder tab buttons changed, they are more compact now 5. With the light theme, chat tabs now have a background when hovering/active tabbing
How it look's like | New reorder tab buttons | Light Chat tabs | | - | - | | ![image](https://github.com/user-attachments/assets/39194331-b69f-473f-ba82-497a86bbe062) | ![image](https://github.com/user-attachments/assets/6fe22bac-2802-4e03-8095-0633b06a5b03) |
General Preview https://github.com/user-attachments/assets/7647d584-c2fd-41b2-b2ee-c7ee61569d1f
## Why It's Good For The Game More accessibility for owners of 2/4k monitors Better appearance NumberInput is behaving extremely strangely in chat ## Changelog :cl: add: Stat Panel now scales like a chat, depends on the font size. Defaults from the chat font size, but you can separate it. refactor: Refactored Stat Panel styles and Byond skin theme applying. Stat Panel now looks more like a TGUI /:cl: --- html/statbrowser.css | 279 +++++++++--------- html/statbrowser.html | 8 +- html/statbrowser.js | 29 +- .../tgui-panel/chat/ChatPageSettings.jsx | 79 +++-- .../tgui-panel/settings/SettingsGeneral.tsx | 80 +++-- .../tgui-panel/settings/middleware.ts | 24 +- tgui/packages/tgui-panel/settings/reducer.ts | 2 + .../tgui-panel/styles/themes/light.scss | 9 +- tgui/packages/tgui-panel/themes.ts | 172 ++++------- 9 files changed, 338 insertions(+), 344 deletions(-) diff --git a/html/statbrowser.css b/html/statbrowser.css index dc693f42f75..cd1d63bf7c0 100644 --- a/html/statbrowser.css +++ b/html/statbrowser.css @@ -1,150 +1,125 @@ body { font-family: Verdana, Geneva, Tahoma, sans-serif; - font-size: 12px !important; + font-size: 12px; margin: 0 !important; padding: 0 !important; - overflow-x: hidden; - overflow-y: scroll; -} - -body.dark { - background-color: #131313; - color: #b2c4dd; - scrollbar-base-color: #1c1c1c; - scrollbar-face-color: #3b3b3b; - scrollbar-3dlight-color: #252525; - scrollbar-highlight-color: #252525; - scrollbar-track-color: #1c1c1c; - scrollbar-arrow-color: #929292; - scrollbar-shadow-color: #3b3b3b; -} - -#menu { - background-color: #F0F0F0; - position: fixed; - width: 100%; - z-index: 100; -} - -.dark #menu { - background-color: #202020; -} - -#statcontent { - padding: 7px 7px 7px 7px; + overflow: hidden; } a { - color: black; - text-decoration: none -} - -.dark a { - color: #b2c4dd; -} - -a:hover, -.dark a:hover { - text-decoration: underline; -} - -ul { - list-style-type: none; - margin: 0; - padding: 0; - background-color: #333; -} - -li { - float: left; -} - -li a { - display: block; - color: white; - text-align: center; - padding: 14px 16px; + color: #003399; text-decoration: none; } -li a:hover:not(.active) { - background-color: #111; +a:hover { + color: #007fff; } -.button-container { - display: inline-flex; - flex-wrap: wrap-reverse; - flex-direction: row; - align-items: flex-start; - overflow-x: hidden; - white-space: pre-wrap; - padding: 0 4px; +h3 { + margin: 0 -0.5em 0.25em; + padding: 1em 0.66em 0.5em; + border-bottom: 0.1667em solid; +} + + +img { + -ms-interpolation-mode: nearest-neighbor; + image-rendering: pixelated; +} + +.stat-container { + display: flex; + flex-direction: column; + height: 100vh; +} + +#menu { + display: flex; + overflow-x: auto; + overflow-y: hidden; + padding: 0.25em 0.25em 0; + background-color: #ffffff; } .button { - background-color: #dfdfdf; - border: 1px solid #cecece; - border-bottom-width: 2px; - color: rgba(0, 0, 0, 0.7); - padding: 6px 4px 4px; - text-align: center; - text-decoration: none; - font-size: 12px; - margin: 0; + display: inline-table; cursor: pointer; - transition-duration: 100ms; - order: 3; - min-width: 40px; -} - -.dark button { - background-color: #222222; - border-color: #343434; - color: rgba(255, 255, 255, 0.5); + user-select: none; + -ms-user-select: none; /* Remove after Byond 516 */ + text-align: center; + font-size: 1em; + min-width: 2.9em; + padding: 0.5em 0.5em 0.4em; + background-color: transparent; + color: rgba(0, 0, 0, 0.5); + border: 0; + border-bottom: 0.1667em solid transparent; + border-radius: 0.25em 0.25em 0 0; } .button:hover { background-color: #ececec; - transition-duration: 0; } -.dark button:hover { - background-color: #2e2e2e; -} - -.button:active, .button.active { - background-color: #ffffff; + background-color: #dfdfdf; color: black; - border-top-color: #cecece; - border-left-color: #cecece; - border-right-color: #cecece; - border-bottom-color: #ffffff; + border-bottom-color: #000000; } -.dark .button:active, -.dark .button.active { - background-color: #444444; - color: white; - border-top-color: #343434; - border-left-color: #343434; - border-right-color: #343434; - border-bottom-color: #ffffff; +#under-menu { + height: 0.5em; + background-color: #eeeeee; +} + +#statcontent { + flex: 1; + padding: 0.75em 0.5em; + overflow-y: scroll; + overflow-x: hidden; } .grid-container { - margin: -2px; - margin-right: -15px; + margin: 0; } .grid-item { + display: inline-flex; position: relative; - display: inline-block; + user-select: none; + -ms-user-select: none; /* Remove after Byond 516 */ width: 100%; box-sizing: border-box; - overflow: visible; - padding: 3px 2px; text-decoration: none; + background-color: transparent; + color: black; +} + +.grid-item:hover { + color: #003399; + z-index: 1; +} + +.grid-item-text { + display: inline-block; + overflow: hidden; + text-overflow: ellipsis; + box-sizing: border-box; + white-space: nowrap; + width: 100%; + padding: 0.33em 0.5em; + border-radius: 0.25em; +} + +.grid-item-text:hover { + position: absolute; + top: -1.33em; + white-space: normal; + background-color: #ececec; +} + +.grid-item-text:active { + background-color: #dfdfdf; } @media only screen and (min-width: 300px) { @@ -171,57 +146,67 @@ li a:hover:not(.active) { } } -.grid-item:hover { - z-index: 1; +.status-info { + margin: 0 0.33em 0.25em; } -.grid-item:hover .grid-item-text { - width: auto; - text-decoration: underline; +.interview_panel_stats, +.interview_panel_controls { + margin-bottom: 1em; } -.grid-item-text { - display: inline-block; - width: 100%; - background-color: #ffffff; - margin: 0 -6px; - padding: 0 6px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - pointer-events: none; +/* Dark theme colors */ +body.dark { + background-color: #131313; + color: #b2c4dd; + scrollbar-base-color: #1c1c1c; + scrollbar-face-color: #3b3b3b; + scrollbar-3dlight-color: #252525; + scrollbar-highlight-color: #252525; + scrollbar-track-color: #1c1c1c; + scrollbar-arrow-color: #929292; + scrollbar-shadow-color: #3b3b3b; } -.dark .grid-item-text { +.dark a { + color: #6699ff; +} + +.dark a:hover, +.dark .grid-item:hover { + color: #80bfff; +} + +.dark #menu { background-color: #131313; } -.link { - display: inline; - background: none; - border: none; - padding: 7px 14px; - color: black; - text-decoration: none; - cursor: pointer; - font-size: 13px; - margin: 2px 2px; +.dark .button { + color: rgba(255, 255, 255, 0.5); } -.dark .link { - color: #abc6ec; +.dark .button:hover { + background-color: #252525; } -.link:hover { - text-decoration: underline; +.dark .button.active { + background-color: #313131; + color: #d4dfec; + border-bottom-color: #d4dfec; } -img { - -ms-interpolation-mode: nearest-neighbor; - image-rendering: pixelated; +.dark #under-menu { + background-color: #202020; } -.interview_panel_controls, -.interview_panel_stats { - margin-bottom: 10px; +.dark .grid-item{ + color: #b2c4dd; +} + +.dark .grid-item-text:hover { + background-color: #252525; +} + +.dark .grid-item-text:active { + background-color: #313131; } diff --git a/html/statbrowser.html b/html/statbrowser.html index 1aea8811d58..ffd7425bd26 100644 --- a/html/statbrowser.html +++ b/html/statbrowser.html @@ -1,3 +1,5 @@ - -
-
+
+ +
+
+
diff --git a/html/statbrowser.js b/html/statbrowser.js index 0d89487af5b..f6c188c6edd 100644 --- a/html/statbrowser.js +++ b/html/statbrowser.js @@ -32,7 +32,6 @@ var turfname = ""; var imageRetryDelay = 500; var imageRetryLimit = 50; var menu = document.getElementById('menu'); -var under_menu = document.getElementById('under_menu'); var statcontentdiv = document.getElementById('statcontent'); var storedimages = []; var split_admin_tabs = false; @@ -58,23 +57,23 @@ function createStatusTab(name) { if (!verb_tabs.includes(name) && !permanent_tabs.includes(name)) { return; } - var B = document.createElement("BUTTON"); - B.onclick = function () { + var button = document.createElement("DIV"); + button.onclick = function () { tab_change(name); this.blur(); + statcontentdiv.focus(); }; - B.id = name; - B.textContent = name; - B.className = "button"; + button.id = name; + button.textContent = name; + button.className = "button"; //ORDERING ALPHABETICALLY - B.style.order = name.charCodeAt(0); + button.style.order = name.charCodeAt(0); if (name == "Status" || name == "MC") { - B.style.order = name == "Status" ? 1 : 2; + button.style.order = name == "Status" ? 1 : 2; } //END ORDERING - menu.appendChild(B); + menu.appendChild(button); SendTabToByond(name); - under_menu.style.height = menu.clientHeight + 'px'; } function removeStatusTab(name) { @@ -88,7 +87,6 @@ function removeStatusTab(name) { } menu.removeChild(document.getElementById(name)); TakeTabFromByond(name); - under_menu.style.height = menu.clientHeight + 'px'; } function sortVerbs() { @@ -104,10 +102,6 @@ function sortVerbs() { }) } -window.onresize = function () { - under_menu.style.height = menu.clientHeight + 'px'; -} - function addPermanentTab(name) { if (!permanent_tabs.includes(name)) { permanent_tabs.push(name); @@ -361,6 +355,7 @@ function draw_status() { } else { var div = document.createElement("div"); div.textContent = status_tab_parts[i]; + div.className = "status-info"; document.getElementById("statcontent").appendChild(div); } } @@ -717,6 +712,10 @@ function set_theme(which) { } } +function set_font_size(size) { + document.body.style.setProperty('font-size', size); +} + function set_style_sheet(sheet) { if (document.getElementById("goonStyle")) { var currentSheet = document.getElementById("goonStyle"); diff --git a/tgui/packages/tgui-panel/chat/ChatPageSettings.jsx b/tgui/packages/tgui-panel/chat/ChatPageSettings.jsx index 4bd0383d7d7..ba577a1e5ef 100644 --- a/tgui/packages/tgui-panel/chat/ChatPageSettings.jsx +++ b/tgui/packages/tgui-panel/chat/ChatPageSettings.jsx @@ -30,7 +30,23 @@ export const ChatPageSettings = (props) => { return (
- + {!!!page.isMain && ( + + - ) : ( - '' - )} - - - - {!page.isMain ? ( - - Reorder Chat:  - - - - ) : ( - '' )} diff --git a/tgui/packages/tgui-panel/settings/SettingsGeneral.tsx b/tgui/packages/tgui-panel/settings/SettingsGeneral.tsx index 8203f031395..3599f24e707 100644 --- a/tgui/packages/tgui-panel/settings/SettingsGeneral.tsx +++ b/tgui/packages/tgui-panel/settings/SettingsGeneral.tsx @@ -8,8 +8,8 @@ import { Divider, Input, LabeledList, - NumberInput, Section, + Slider, Stack, } from 'tgui/components'; @@ -20,10 +20,11 @@ import { FONTS } from './constants'; import { selectSettings } from './selectors'; export function SettingsGeneral(props) { - const { theme, fontFamily, fontSize, lineHeight } = + const { theme, fontFamily, fontSize, lineHeight, statLinked, statFontSize } = useSelector(selectSettings); const dispatch = useDispatch(); const [freeFont, setFreeFont] = useState(false); + const [statFont, setStatFont] = useState(false); return (
@@ -109,35 +110,66 @@ export function SettingsGeneral(props) { )} - - toFixed(value)} - onChange={(value) => - dispatch( - updateSettings({ - fontSize: value, - }), - ) - } - /> + + + + toFixed(value)} + onChange={(e, value) => + dispatch( + updateSettings({ + [statFont ? 'statFontSize' : 'fontSize']: value, + }), + ) + } + /> + + + + + {!!statFont && ( + +