键位搜索与过滤

基本信息

属性 值
过滤枚举 com.blamejared.controlling.client.gui.DisplayMode(3 值)
搜索枚举 com.blamejared.controlling.client.gui.SearchType(4 值)
排序枚举 com.blamejared.controlling.client.gui.SortOrder(3 值)
作用对象 GuiNewKeyBindingList.KeyEntry 列表项
组合方式 过滤谓词 and 搜索谓词,先过滤再排序

功能

原版控制设置界面的按键列表只能滚动浏览。本 mod 为它加上了过滤、搜索与排序三重能力。 三个枚举各自提供一个策略,GuiNewControls.filterKeys() 把它们串成流水线:

  1. displayMode.getPredicate() —— 过滤谓词;
  2. .and(searchType.getPredicate(searchTextBox.getText())) —— 叠加搜索谓词;
  3. 遍历 guiNewKeyBindingList.getAllEntries(),保留通过筛选的 KeyEntry;
  4. sortOrder.sort(keysToDisplay) —— 排序;
  5. 按分类重新插入 CategoryEntry 标题行;
  6. setDisplayedEntries(...) 回填列表。

过滤开始前会先 scrollBy(-getAmountScrolled()) 把滚动位置复位。 搜索框文本变化时(updateScreen 中比对 lastSearch)会触发整条流水线重跑。

DisplayMode —— 显示模式(3 值)

控制界面上对应两个可切换按钮:“显示未绑定”(ID 1003)与 “显示冲突”(ID 1004)。 两者互斥切换;任一按钮被按下后会把另一个按钮的文案复位。

取值 谓词逻辑 触发按钮文案
ALL keyEntry -> true,全部显示 默认状态(初始字段值)
CONFLICTING 见下方细则 options.showConflicts / options.showAll
UNBOUND keyEntry.getKeybinding().getKeyCode() == 0 options.showNone / options.showAll

CONFLICTING 细则:遍历 gameSettings.keyBindings,跳过自身以及 getKeyCode() == 0 的绑定,然后

  • 若两者都是 ComboKeyBinding → 采用 controlling$conflicts(keyEntry.getKeybinding()) (即键码与修饰键都相同才算冲突);
  • 否则 → 采用朴素比较 keyBinding.getKeyCode() == keyEntry.getKeybinding().getKeyCode()。

任一绑定命中即返回 true。

注意:过滤用的 CONFLICTING 采用硬冲突判定(controlling$conflicts), 而列表行的 [ ] 标记区分硬/软两种。软冲突(G 与 Ctrl + G)不会出现在 "显示冲突"结果里,但在列表中仍以金色 [ ] 提示。

SearchType —— 搜索范围(4 值)

对应两个互斥复选框:“Key”(ID 1005)与 “Category”(ID 1006)。 点击其中之一会把另一个取消勾选;两者都未勾选时回到 ALL。 初始字段值为 SearchType.ALL。

取值 匹配字段 判定
ALL 三者取并集 CATEGORY_NAME.getPredicate(t).or(KEYBIND_NAME.getPredicate(t)).or(KEY_NAME.getPredicate(t))
CATEGORY_NAME 分类名 StatCollector.translateToLocal(keybinding.getKeyCategory()).toLowerCase().contains(search)
KEYBIND_NAME 按键本身的名字 key.getKeyDesc().toLowerCase().contains(search)
KEY_NAME 当前绑定的键(含修饰键) 见下方细则

所有比较都是两侧 toLowerCase() 后 contains,所以大小写不敏感且为子串匹配。

KEY_NAME 细则:显示名来源分两种情况——

  • 该按键是 ComboKeyBinding → controlling$getDisplayName(),形如 Ctrl + G;
  • 否则 → 原版 GameSettings.getKeyDisplayString(keyCode)。

因此按 Ctrl 也能搜出 Ctrl + G 的绑定,按 G 也能命中。

KEYBIND_NAME 虽然在界面复选框里没有直接对应的按钮(只有 Key 与 Category 两个), 但它是 ALL 的组成部分,也参与列表左侧标签的搜索高亮判断。

SortOrder —— 排序方式(3 值)

控制界面上的排序按钮(ID 1008)。按钮显示的不是当前排序,而是下一个排序 (options.sort + ": " + sortOrder.getNextName()),点击才切换。

取值 显示名(i18n) sort() 行为
VANILLA options.sortNone = Vanilla 直接 return,不做任何排序
AZ options.sortAZ = A->Z list.sort(Comparator.comparing(KeyEntry::getKeyDesc))
ZA options.sortZA = Z->A 同上但 .reversed()
  • 初始字段值为 SortOrder.VANILLA;
  • getNext() 按 VALUES[(ordinal() + 1) % VALUES.length] 循环,顺序为 VANILLA → AZ → ZA → VANILLA。

比较的是按键名而非键名:AZ/ZA 都用 KeyEntry::getKeyDesc(按 I18n.format(getKeyDescription()) 得到的本地化按键描述),不是显示的键(如 Ctrl + G)。 VANILLA 保留列表构造时 Arrays.sort(KeyBinding[]) 得到的原版默认顺序。

搜索高亮

命中搜索词时,列表用黄色背景(0xFFDFD407)+ 深灰文字(0x404040)标出子串。 哪一部分会被高亮,取决于当前 SearchType:

列表区域 高亮条件
分类标题行 搜索词非空 且 SearchType 为 ALL 或 CATEGORY_NAME
左侧按键名标签 搜索词非空 且 SearchType 为 ALL 或 KEYBIND_NAME
右侧按键显示名按钮 搜索词非空 且 SearchType 为 ALL 或 KEY_NAME 且按钮文本中确实含该子串

分类标题为选中状态时被判定为高亮,绘制时会套用下划线格式。

相关条目