让鼠标滚轮能滚列表:把列表 ScrollPane 的 touchable 从默认 childrenOnly 改成 enabled(无参返回枚举的方法=getTouchable,枚举 dv 第0常量=enabled)
- 诊断证据:程序化 scrollY(200) 生效(before=0 after=200),说明可滚范围没问题, 是滚轮事件没送到面板 —— 因为 childrenOnly 时 ScrollPane 自己不是命中目标,收不到 enter、 也就不会 setScrollFocus。 - 顺带把这条 Actor/Touchable 映射写进 anchors.tsv + names.tsv。
This commit is contained in:
1 parent
d59287937d
commit
13bce4509d
3 files changed
+73
No files matched your search
@@ -84,6 +84,7 @@ public final class ObjectPanel {
|
||||
call(state.listTable, Obf.TABLE_LEFT, new Class<?>[0], tableClass);
|
||||
Object scroll = scrollClass.getConstructor(actorClass, skinClass).newInstance(state.listTable, skin);
|
||||
state.listScroll = scroll;
|
||||
makeTouchable(scroll);
|
||||
state.status = label(loader, skin, "Ready. Press Refresh to list scene objects.");
|
||||
Object logScroll = null;
|
||||
state.nameField = fieldClass.getConstructor(String.class, skinClass)
|
||||
@@ -537,6 +538,64 @@ public final class ObjectPanel {
|
||||
state.logBlockStarted = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 把 ScrollPane 的 touchable 设成 `enabled`(它默认是 childrenOnly)。
|
||||
*
|
||||
* 为什么:ScrollPane 是靠自己的 InputListener 在鼠标"进入"时调 `Stage.setScrollFocus(this)`
|
||||
* 来接收滚轮的;childrenOnly 时它自己不是命中目标,就永远收不到 enter → 滚轮事件不会送到它,
|
||||
* 表现就是"面板能程序化滚动,但鼠标滚轮没用"。
|
||||
*
|
||||
* 不靠名字定位:`Actor.getTouchable()` 是"**无参 + 返回枚举**"的那个方法;枚举第 0 个常量
|
||||
* 就是 `Touchable.enabled`(libGDX 的声明顺序 enabled/disabled/childrenOnly)。
|
||||
*/
|
||||
static void makeTouchable(Object actor) {
|
||||
try {
|
||||
Class<?> enumType = null;
|
||||
for (Method method : actor.getClass().getMethods()) {
|
||||
if (method.getParameterTypes().length != 0) continue;
|
||||
Class<?> returns = method.getReturnType();
|
||||
if (!returns.isEnum()) continue;
|
||||
enumType = returns;
|
||||
break;
|
||||
}
|
||||
if (enumType == null) {
|
||||
System.err.println("[panel] 找不到 Touchable 枚举,跳过");
|
||||
return;
|
||||
}
|
||||
Object[] constants = enumType.getEnumConstants();
|
||||
if (constants == null || constants.length == 0) return;
|
||||
Object enabled = constants[0];
|
||||
for (Method method : actor.getClass().getMethods()) {
|
||||
Class<?>[] types = method.getParameterTypes();
|
||||
if (types.length != 1 || types[0] != enumType) continue;
|
||||
if (method.getReturnType() != void.class) continue;
|
||||
method.setAccessible(true);
|
||||
method.invoke(actor, enabled);
|
||||
System.err.println("[panel] ScrollPane.touchable = " + enabled
|
||||
+ "(枚举 " + enumType.getName() + " 第 0 个常量)");
|
||||
return;
|
||||
}
|
||||
System.err.println("[panel] 找不到 setTouchable");
|
||||
} catch (Throwable error) {
|
||||
System.err.println("[panel] 设置 touchable 失败: " + error);
|
||||
}
|
||||
}
|
||||
|
||||
private static float readFloat(Object target, String name) {
|
||||
try {
|
||||
for (Method method : target.getClass().getMethods()) {
|
||||
if (!method.getName().equals(name)) continue;
|
||||
if (method.getParameterTypes().length != 0) continue;
|
||||
if (method.getReturnType() != float.class) continue;
|
||||
method.setAccessible(true);
|
||||
return ((Float) method.invoke(target)).floatValue();
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
// 读不到就返回 -1
|
||||
}
|
||||
return -1f;
|
||||
}
|
||||
|
||||
private static void invalidateList(final State state) {
|
||||
try {
|
||||
call(state.listTable, "b_", new Class<?>[0], void.class);
|
||||
@@ -563,6 +622,13 @@ public final class ObjectPanel {
|
||||
// 再打开"强制纵向滚动":setForceScroll 在载荷里叫 `I`((ZZ)V,指纹确认 ~2/3)
|
||||
call(state.listScroll, "I", new Class<?>[] {boolean.class, boolean.class}, void.class,
|
||||
Boolean.FALSE, Boolean.TRUE);
|
||||
// 诊断(只读+可回滚):读一下当前滚动位置,再程序化滚 200,再读一次。
|
||||
// before/after 都写日志:如果 after 还是 0 → 说明 ScrollPane 认为"内容装得下"(高度没测到);
|
||||
// 如果 after 变成 200 → 说明面板能滚,是滚轮事件没送到面板。
|
||||
float before = readFloat(state.listScroll, "invoke");
|
||||
call(state.listScroll, "Class", new Class<?>[] {float.class}, void.class, Float.valueOf(200f));
|
||||
float after = readFloat(state.listScroll, "invoke");
|
||||
System.err.println("[panel] scroll diag: before=" + before + " after=" + after);
|
||||
} catch (Throwable error) {
|
||||
System.err.println("[panel] 恢复滚动失败: " + error);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user