键位搜索与过滤
基本信息
| 属性 | 值 |
|---|---|
| 过滤枚举 | 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() 把它们串成流水线:
displayMode.getPredicate()—— 过滤谓词;.and(searchType.getPredicate(searchTextBox.getText()))—— 叠加搜索谓词;- 遍历
guiNewKeyBindingList.getAllEntries(),保留通过筛选的KeyEntry; sortOrder.sort(keysToDisplay)—— 排序;- 按分类重新插入
CategoryEntry标题行; 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 且按钮文本中确实含该子串 |
分类标题为选中状态时被判定为高亮,绘制时会套用下划线格式。