Index: binaries/data/config/default.cfg =================================================================== --- binaries/data/config/default.cfg +++ binaries/data/config/default.cfg @@ -206,7 +206,6 @@ [hotkey.camera] reset = "R" ; Reset camera rotation to default. follow = "F" ; Follow the first unit in the selection -rallypointfocus = "" ; Focus the camera on the rally point of the selected building zoom.in = Plus, NumPlus ; Zoom camera in (continuous control) zoom.out = Minus, NumMinus ; Zoom camera out (continuous control) zoom.wheel.in = WheelUp ; Zoom camera in (stepped control) Index: binaries/data/mods/public/gui/common/color.js =================================================================== --- binaries/data/mods/public/gui/common/color.js +++ binaries/data/mods/public/gui/common/color.js @@ -3,6 +3,8 @@ */ var g_HotkeyTags = { "color": "255 251 131" }; +var g_UnavaibleHotkeyTags = { "color": "204 51 0", "font": "sans-13" }; + /** * Concatenate integer color values to a string (for use in GUI objects) * @@ -175,15 +177,13 @@ // TODO: Be more efficient in retrieving the mapping(s) for a specific hotkey let key = Engine.GetHotkeyMap()[hotkey]; - if (!key) - key = sprintf(translate("Unassigned hotkey: %(hotkeyName)s"), { - "hotkeyName": hotkey - }); - else - key = formatHotkeyCombinations(key); + if (!formatHotkeyCombinations(key)) + return setStringTags("\\[" + sprintf(translate("Unassigned hotkey \"%(hotkeyName)s\""), { + "hotkeyName": translateWithContext("hotkey metadata", getReadableHotkeyName(hotkey)) + }) + "]\n", g_UnavaibleHotkeyTags); return sprintf(text, { - "hotkey": setStringTags("\\[" + key + "]", g_HotkeyTags) + "hotkey": setStringTags("\\[" + formatHotkeyCombinations(key) + "]", g_HotkeyTags) }); } Index: binaries/data/mods/public/gui/common/hotkeys.js =================================================================== --- binaries/data/mods/public/gui/common/hotkeys.js +++ binaries/data/mods/public/gui/common/hotkeys.js @@ -3,6 +3,8 @@ */ var g_ScancodesMap; +var g_HotkeyNames = new Map(); + function hotkeySort(a, b) { const specialKeys = ["Shift", "Alt", "Ctrl", "Super"]; @@ -37,3 +39,23 @@ combs.sort((a, b) => a.length - b.length || a - b); return translateScancodes ? combs.join(", ") : combs; } + +function getHotkeyFiles() +{ + return Engine.ListDirectoryFiles("gui/hotkeys/spec/", "*.json"); +} + +function getReadableHotkeyName(key) +{ + if (!g_HotkeyNames.size) + for (let file of getHotkeyFiles()) + { + let data = Engine.ReadJSONFile(file); + if (data.mapped_hotkeys) + for (let cat in data.mapped_hotkeys) + for (let hotkey in data.mapped_hotkeys[cat]) + g_HotkeyNames.set(hotkey, data.mapped_hotkeys[cat][hotkey].name); + } + + return g_HotkeyNames.get(key); +} Index: binaries/data/mods/public/gui/hotkeys/HotkeyMetadata.js =================================================================== --- binaries/data/mods/public/gui/hotkeys/HotkeyMetadata.js +++ binaries/data/mods/public/gui/hotkeys/HotkeyMetadata.js @@ -14,7 +14,7 @@ parseSpec() { - let files = this.getFiles(); + let files = getHotkeyFiles(); let hotkey_i = 0; let categories = { [this.DEFAULT_CATEGORY]: { @@ -59,11 +59,6 @@ this.categories[key] = categories[key]; // TODO: validate that categories exist. } - - getFiles() - { - return Engine.ListDirectoryFiles("gui/hotkeys/spec/", "*.json"); - } } HotkeyMetadata.prototype.DefaultCategoryString = markForTranslation("Other Hotkeys"); Index: binaries/data/mods/public/gui/session/MenuButtons.js =================================================================== --- binaries/data/mods/public/gui/session/MenuButtons.js +++ binaries/data/mods/public/gui/session/MenuButtons.js @@ -87,7 +87,7 @@ rebuild() { - this.button.tooltip = sprintf(translate("Press %(hotkey)s to open the summary screen."), { + this.button.tooltip = sprintf(translate("%(hotkey)s Open the summary screen."), { "hotkey": colorizeHotkey("%(hotkey)s", this.button.hotkey), }); } @@ -139,7 +139,7 @@ rebuild() { - this.button.tooltip = sprintf(translate("Press %(hotkey)s to open the multiplayer lobby page without leaving the game."), { + this.button.tooltip = sprintf(translate("%(hotkey)s Open the multiplayer lobby page without leaving the game."), { "hotkey": colorizeHotkey("%(hotkey)s", this.button.hotkey), }); } @@ -218,7 +218,7 @@ { this.button.enabled = this.pauseControl.canPause(true); this.button.caption = this.pauseControl.explicitPause ? translate("Resume") : translate("Pause"); - this.button.tooltip = sprintf(translate("Press %(hotkey)s to pause or resume the game."), { + this.button.tooltip = sprintf(translate("%(hotkey)s Pause or resume the game."), { "hotkey": colorizeHotkey("%(hotkey)s", this.button.hotkey), }); }