diff --git a/code/_globalvars/tgui.dm b/code/_globalvars/tgui.dm index 6174a78a4ce..a81078420f5 100644 --- a/code/_globalvars/tgui.dm +++ b/code/_globalvars/tgui.dm @@ -1,3 +1,4 @@ GLOBAL_DATUM(crew_manifest_tgui, /datum/crew_manifest) GLOBAL_DATUM(changelog_tgui, /datum/changelog) +GLOBAL_DATUM(hotkeys_tgui, /datum/hotkeys_help) GLOBAL_DATUM(record_manifest_tgui, /datum/record_manifest) //SKYRAT EDIT ADDITION -- EXPLOITABLE VERB diff --git a/code/datums/hotkeys_help.dm b/code/datums/hotkeys_help.dm new file mode 100644 index 00000000000..1f388a264c2 --- /dev/null +++ b/code/datums/hotkeys_help.dm @@ -0,0 +1,40 @@ +/datum/hotkeys_help + var/static/list/hotkeys = list() + +/datum/hotkeys_help/ui_state() + return GLOB.always_state + +/datum/hotkeys_help/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if (!ui) + ui = new(user, src, "HotkeysHelp") + ui.open() + +// Not static data since user could rebind keys. +/datum/hotkeys_help/ui_data(mob/user) + // List every keybind to chat. + var/list/keys_list = list() + + // Show them in alphabetical order by key + var/list/key_bindings_by_key = user.client.prefs.key_bindings_by_key.Copy() + sortTim(key_bindings_by_key, cmp = /proc/cmp_text_asc) + + for(var/key in key_bindings_by_key) + // Get the full names + var/list/binding_names = list() + for(var/kb_name in key_bindings_by_key[key]) + var/datum/keybinding/binding = GLOB.keybindings_by_name[kb_name] + binding_names += list(list( + "name" = binding.full_name, + "desc" = binding.description + )) + + // Add to list + keys_list += list(list( + "key" = key, + "bindings" = binding_names + )) + + return list( + "hotkeys" = keys_list + ) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 161e8420b0d..35b841beaf8 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -1161,6 +1161,9 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if (verbpath.name[1] != "@") new child(src) + // Place Help back at the end. + winset(src, "help-menu", "index=1000") + /client/proc/open_filter_editor(atom/in_atom) if(holder) holder.filteriffic = new /datum/filter_editor(in_atom) diff --git a/interface/interface.dm b/interface/interface.dm index f092a43fe33..a32bb758a20 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -109,3 +109,12 @@ prefs.lastchangelog = GLOB.changelog_hash prefs.save_preferences() winset(src, "infowindow.changelog", "font-style=;") + +/client/verb/hotkeys_help() + set name = "Hotkeys Help" + set category = "OOC" + + if(!GLOB.hotkeys_tgui) + GLOB.hotkeys_tgui = new /datum/hotkeys_help() + + GLOB.hotkeys_tgui.ui_interact(mob) diff --git a/interface/skin.dmf b/interface/skin.dmf index bad4154f239..f29bffeb22f 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -39,7 +39,7 @@ menu "menu" command = ".quit" category = "&File" saved-params = "is-checked" - elem + elem "help-menu" name = "&Help" command = "" saved-params = "is-checked" @@ -50,7 +50,7 @@ menu "menu" saved-params = "is-checked" elem name = "&Hotkeys" - command = "hotkeys-help" + command = "Hotkeys-Help" category = "&Help" saved-params = "is-checked" diff --git a/tgstation.dme b/tgstation.dme index aad53e2413b..301e3608a9b 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -612,6 +612,7 @@ #include "code\datums\forced_movement.dm" #include "code\datums\hailer_phrase.dm" #include "code\datums\holocall.dm" +#include "code\datums\hotkeys_help.dm" #include "code\datums\http.dm" #include "code\datums\hud.dm" #include "code\datums\map_config.dm" diff --git a/tgui/packages/tgui/interfaces/HotkeysHelp.tsx b/tgui/packages/tgui/interfaces/HotkeysHelp.tsx new file mode 100644 index 00000000000..4d67927abfd --- /dev/null +++ b/tgui/packages/tgui/interfaces/HotkeysHelp.tsx @@ -0,0 +1,135 @@ +import { useBackend } from '../backend'; +import { + Box, + Section, + Table, + Tooltip, +} from '../components'; +import { Window } from '../layouts'; + +type BindingInfo = { + name: string; + desc: string; +} + +type HotkeyInfo = { + key: string; + bindings: BindingInfo[]; +} + +type HotkeysHelpData = { + hotkeys: HotkeyInfo[]; +}; + +type KeyBindingBoxProps = { + keycode: string, +} + +type ModkeyProps = { + text: string, + color: string +} + +const shiftRegex = /(.*)(Shift)(.*)/; +const ctrlRegex = /(.*)(Ctrl)(.*)/; +const altRegex = /(.*)(Alt)(.*)/; + +const addColorModifier = (content: string, regex: RegExp, color: string): + JSX.Element | null => { + const match = content.match(regex); + + if (match) { + return ( + <> + {processColorModifiers(match[1])} + {match[2]} + {processColorModifiers(match[3])} + + ); + } + + return null; +}; + +const processColorModifiers = (content: string): string | JSX.Element => { + const shifted = addColorModifier(content, shiftRegex, "#88f"); + + if (shifted) { + return shifted; + } + + const ctrled = addColorModifier(content, ctrlRegex, "#8f8"); + + if (ctrled) { + return ctrled; + } + + const alted = addColorModifier(content, altRegex, "#fc4"); + + if (alted) { + return alted; + } + + // Fix the weirdly named keys + + return ` ${content}` + .replace("Northeast", "Page Up") + .replace("Southeast", "Page Down") + .replace("Northwest", "Home") + .replace("Southwest", "End") + .replace("North", "Up") + .replace("South", "Down") + .replace("East", "Right") + .replace("West", "Left") + .replace("Numpad", "Numpad "); +}; + +const KeyBinding = (props: KeyBindingBoxProps) => ( + <>{processColorModifiers(props.keycode)} +); + +export const HotkeysHelp = (_, context) => { + const { data } = useBackend(context); + + return ( + + +
+ + + + Key + + + Binding + + + {data.hotkeys.map(hotkey => ( + + + + + + {hotkey.bindings.map(binding => ( + binding.desc + ? ( + + + {binding.name} + + + ) : ( + + {binding.name} + + ) + ))} + + + ))} +
+
+
+
+ ); +}; diff --git a/tgui/packages/tgui/styles/interfaces/HotKeysHelp.scss b/tgui/packages/tgui/styles/interfaces/HotKeysHelp.scss new file mode 100644 index 00000000000..6bc74bcabfd --- /dev/null +++ b/tgui/packages/tgui/styles/interfaces/HotKeysHelp.scss @@ -0,0 +1,4 @@ +.HotkeysHelp__pill { + border-radius: 5px; + background-color: rgba(255, 255, 255, 0.125); +} diff --git a/tgui/packages/tgui/styles/main.scss b/tgui/packages/tgui/styles/main.scss index 33c746f0eab..4ec9163a32a 100644 --- a/tgui/packages/tgui/styles/main.scss +++ b/tgui/packages/tgui/styles/main.scss @@ -54,6 +54,7 @@ @include meta.load-css('./interfaces/CrewManifest.scss'); @include meta.load-css('./interfaces/ExperimentConfigure.scss'); @include meta.load-css('./interfaces/HellishRunes.scss'); +@include meta.load-css('./interfaces/HotkeysHelp.scss'); @include meta.load-css('./interfaces/Hypertorus.scss'); @include meta.load-css('./interfaces/LibraryComputer.scss'); @include meta.load-css('./interfaces/NuclearBomb.scss');