File size: 9,777 Bytes
b6a38d7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
if FirstLoad then
MouseButtonImagesInText = {
-- Add project specific images
--[[["MouseL"] = "UI/Infopanel/left_click.tga",
["MouseR"] = "UI/Infopanel/right_click.tga",
["MouseM"] = "UI/Infopanel/middle_click.tga",
["MouseX1"] = "UI/Infopanel/button_4.tga",
["MouseX2"] = "UI/Infopanel/button_5.tga",
["MouseWheelFwd"] = "UI/Infopanel/scroll_up.tga",
["MouseWheelBack"] = "UI/Infopanel/scroll_down.tga",]]
}
MouseButtonNames = {
MouseL = T(344793107847, "Left Mouse Button"),
MouseR = T(620781110653, "Right Mouse Button"),
MouseM = T(814937893055, "Middle Mouse Button"),
MouseX1 = T(404129049676, "Mouse Button 4"),
MouseX2 = T(640322216255, "Mouse Button 5"),
MouseWheelFwd = T(286518835802, "Mouse Wheel Forward"),
MouseWheelBack = T(889465032724, "Mouse Wheel Back"),
}
ForbiddenShortcutKeys = {
Lwin = true,
Rwin = true,
Menu = true,
MouseL = true,
MouseR = true,
MouseM = true,
Enter = true,
}
NonBindableKeys = {}
end
function GatherNonBindableKeys()
local nonBindableKeys = {}
for _, action in ipairs(XShortcutsTarget:GetActions()) do
if action.ActionMode ~= "Editor" and not action.ActionBindable then
table.insert(nonBindableKeys, action)
end
end
return nonBindableKeys
end
TFormat.GamepadShortcutName = function(context_obj, shortcut)
if not shortcut or shortcut == "" then
return T(879415238341, "<negative>Unassigned</negative>")
end
local buttons = SplitShortcut(shortcut)
for i, button in ipairs(buttons) do
buttons[i] = const.TagLookupTable[button] or GetPlatformSpecificImageTag(button) or "?"
end
return Untranslated(table.concat(buttons))
end
EmShortcutNames = false
ShortcutIconScale = " 1000"
TFormat.KeyboardAndMouseShortcutName = function(context_obj, shortcut, scale, unassigned_str)
if not shortcut or shortcut == "" then
return unassigned_str or T(879415238341, "<negative>Unassigned</negative>")
end
local keys = SplitShortcut(shortcut)
scale = scale or ShortcutIconScale
local texts = {}
for _, key in ipairs(keys) do
local img = MouseButtonImagesInText[key]
if img then
texts[#texts + 1] = Untranslated("<image " .. img .. scale .. ">")
goto continue
end
local text = MouseButtonNames[key] or KeyNames[VKStrNamesInverse[key]]
assert(text, "Unknown mouse button name")
if not text then
goto continue
end
if EmShortcutNames then
texts[#texts + 1] = T{399372771879, "<em><name></em>", name = text}
else
texts[#texts + 1] = T{629765447024, "<name>", name = text}
end
::continue::
end
return table.concat(texts, "-")
end
TFormat.ShortcutName = function(context_obj, action_id, source, scale)
local shortcuts = GetShortcuts(action_id)
if GetUIStyleGamepad() and (not source or source == "gamepad") then
return TFormat.GamepadShortcutName(context_obj, shortcuts and shortcuts[3])
else
return TFormat.KeyboardAndMouseShortcutName(context_obj, shortcuts and shortcuts[1], scale)
end
end
TwinShortcuts = {
DPadUp = { DPadDown = "DPadUpDown" },
DPadDown = { DPadUp = "DPadUpDown" },
DPadLeft = { DPadRight = "DPadLeftRight" },
DPadRight = { DPadLeft = "DPadLeftRight" },
}
local function GetTwinShortcutIcon(shortcut1, shortcut2)
if not shortcut1 or shortcut1 == "" then return end
if not shortcut2 or shortcut2 == "" then return end
local buttons1 = SplitShortcut(shortcut1)
local buttons2 = SplitShortcut(shortcut2)
local button_cnt = #buttons1
if button_cnt ~= #buttons2 then return end
for i = 1, button_cnt - 1 do
if buttons1[i] ~= buttons2[i] then return end
end
local twin_button = table.get(TwinShortcuts[buttons1[button_cnt]], buttons2[button_cnt])
if not twin_button then return end
local twin_shortcut_icon = const.TagLookupTable[twin_button] or GetPlatformSpecificImageTag(twin_button)
return twin_shortcut_icon, buttons1
end
TwinShortcutSeparator = T(522258393731, " / ")
--- Combines two related shortcuts into one
-- If RT+DPadUp and RT+DPadDown are passed then the return value will be RT+DPadUpDown.
-- Shortcut relations are specified in the TwinShortcuts table.
-- If two unrelated shortcuts are passed then the return value will be those shortcuts concatenated with TwinShortcutSeparator.
TFormat.TwinShortcutNames = function(context_obj, action1_id, action2_id, source, separator)
local shortcuts1 = GetShortcuts(action1_id)
local shortcuts2 = GetShortcuts(action2_id)
local shortcut1, shortcut2, shortcut_name_func
if GetUIStyleGamepad() and (not source or source == "gamepad") then
shortcut1 = shortcuts1 and shortcuts1[3]
shortcut2 = shortcuts2 and shortcuts2[3]
shortcut_name_func = TFormat.GamepadShortcutName
else
shortcut1 = shortcuts1 and shortcuts1[1]
shortcut2 = shortcuts2 and shortcuts2[1]
shortcut_name_func = TFormat.KeyboardAndMouseShortcutName
end
local twin_shortcut_icon, buttons = GetTwinShortcutIcon(shortcut1, shortcut2)
if twin_shortcut_icon then
local button_cnt = #buttons
for i = 1, button_cnt - 1 do
local button = buttons[i]
buttons[i] = const.TagLookupTable[button] or GetPlatformSpecificImageTag(button) or "?"
end
buttons[button_cnt] = twin_shortcut_icon
return Untranslated(table.concat(buttons))
else
return Untranslated(table.concat({
shortcut_name_func(context_obj, shortcut1),
shortcut_name_func(context_obj, shortcut2)
}, separator or TwinShortcutSeparator))
end
end
function ShortcutKeysToText(keys)
local texts = {}
for k, v in ipairs(keys) do
texts[k] = MouseButtonNames[v] or KeyNames[VKStrNamesInverse[v]]
end
return table.concat(texts, "-")
end
EmptyKeyImageInText = false
KeybindingImageScale = " 1100"
function KeybindingName(shortcut)
local empty_key = EmptyKeyImageInText and Untranslated("<image " .. EmptyKeyImageInText .. KeybindingImageScale .. ">") or ""
return TFormat.KeyboardAndMouseShortcutName(nil, shortcut, KeybindingImageScale, empty_key)
end
function RebindKeys(idx, prop_ctrl)
CreateRealTimeThread(function(idx, prop_ctrl)
local obj = ResolvePropObj(prop_ctrl.context)
local prop_meta = prop_ctrl.prop_meta
local prop_id = prop_meta.id
local prop_name = prop_meta.name
local dlg = CreateMessageBox(terminal.desktop, T(""), T{529975158495, "Press a key to assign to <action>...\nPress Esc to cancel.", action = prop_name})
dlg:PreventClose()
local shortcut, keys, last_key
repeat
shortcut = WaitShortcut()
if prop_ctrl.window_state == "destroying" then
dlg:Close()
return
end
if shortcut then
keys = SplitShortcut(shortcut)
last_key = keys[#keys]
if shortcut ~= "Escape" then
Msg("OptionsChanged")
end
end
until shortcut and not ForbiddenShortcutKeys[last_key] and not (prop_meta.single_key and (last_key == "Ctrl" or last_key == "Shift"))
if prop_meta.single_key then
shortcut = last_key
keys = {last_key}
end
shortcut = last_key ~= "Escape" and shortcut
if MouseButtonNames[last_key] and not prop_meta.mouse_bindable then
local parent = dlg.parent
dlg:Close()
CreateMessageBox(parent, T(207596731516, "Conflicting controls"),
T{301773001578, "<key> cannot be used for <action>.",
key = MouseButtonNames[last_key] or T{last_key}, action = prop_name},
T(325411474155, "OK"))
return
end
local nonRebindableAction = table.find_value(NonBindableKeys, "ActionShortcut", last_key)
if shortcut and nonRebindableAction and EnabledInModes(nonRebindableAction.ActionMode, prop_meta.mode) then
local parent = dlg.parent
dlg:Close()
CreateMessageBox(parent, T(207596731516, "Conflicting controls"),
T{163533339775, "<newKey> is already used by a non rebindable action <nonRebindableKey>",
newKey = KeybindingName(last_key) or T{last_key}, nonRebindableKey = nonRebindableAction.ActionTranslate and nonRebindableAction.ActionName or ""},
T(325411474155, "OK"))
return
end
if shortcut then
for _, ctrl in ipairs(prop_ctrl.parent) do
local ctrl_meta = ctrl.prop_meta
if not ctrl_meta then goto continue end
local bindings = obj[ctrl_meta.id]
if bindings and EnabledInModes(ctrl_meta.mode, prop_meta.mode) then
for i = 1, #bindings do
if ctrl_meta.id ~= prop_id and bindings[i] == shortcut then
local old_action = ctrl_meta.name
local new_action = prop_name
if dlg.window_state == "open" then
dlg:Close()
end
local res = WaitQuestion(terminal.desktop,
T(207596731516, "Conflicting controls"),
T{905663676426, "Do you want to rebind <key> from <old_action> to <new_action>?",
key = ShortcutKeysToText(keys),
old_action = old_action,
new_action = new_action
},
T(689884995409, "Yes"),
T(782927325160, "No")
)
if res == "ok" then
-- clear binding
bindings = table.copy(bindings) --don't overwrite the default values
bindings[1] = i ~= 1 and bindings[1] or bindings[2] or ""
bindings[2] = ""
obj:SetProperty(ctrl_meta.id, bindings)
ctrl.value = bindings
ctrl:OnPropUpdate(ctrl.context, ctrl_meta, bindings)
break
else
return
end
end
end
end
::continue::
end
local bindings = obj[prop_meta.id]
bindings = bindings and table.copy(bindings) or {} --don't overwrite the default values
idx = bindings[1] and idx or 1
bindings[idx] = shortcut
if #bindings > 1 and bindings[1] == bindings[2] then
bindings[2] = ""
end
obj:SetProperty(prop_meta.id, bindings)
prop_ctrl.value = bindings
prop_ctrl:OnPropUpdate(prop_ctrl.context, prop_meta, bindings)
end
if dlg and dlg.window_state ~= "destroying" then
dlg:Close()
end
end, idx, prop_ctrl)
end
ShouldAttachSelectionShortcutWork = return_true
ShouldBlackPlanesShortcutWork = return_true |