面板改为上/中/下三段:上=按钮(自适应)、中=列表(expand+fill 吃掉剩余)、下=实时提示(保留最近6条,多行)

This commit is contained in:
tianmo committed 2026-10-16 15:57:36 +08:00
1 parent 7f5ee1f00e
commit 1cfd5e13cd
1 file changed
+37 -3
+37 -3
View File
@@ -40,6 +40,7 @@ public final class ObjectPanel {
Object status;
String statusText;
Object nameField;
final java.util.Deque<String> log = new java.util.ArrayDeque<String>();
List<Object> objects = new ArrayList<Object>();
Object target;
}
@@ -68,7 +69,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;
state.status = label(loader, skin, "Press Refresh to list scene objects.");
state.status = label(loader, skin, "Ready. Press Refresh to list scene objects.");
state.nameField = fieldClass.getConstructor(String.class, skinClass)
.newInstance("particle_bone", skin);
@@ -98,9 +99,13 @@ public final class ObjectPanel {
Object cell = call(root, Obf.TABLE_ADD, new Class<?>[] {actorClass}, cellClass, state.nameField);
layoutCell(cell, Obf.CELL_LEFT);
call(root, Obf.TABLE_ROW, new Class<?>[0], cellClass);
// 列表区:唯一 expand+fill 的单元格,吃掉剩下的高度
// 中段:列表区 —— 唯一 expand+fill 的单元格,吃掉剩余的高度
cell = call(root, Obf.TABLE_ADD, new Class<?>[] {actorClass}, cellClass, scroll);
layoutCell(cell, Obf.CELL_TOP, Obf.CELL_EXPAND, Obf.CELL_FILL);
// 下段:实时提示(多行、只靠左,不加 fill,保持自然高度贴在底部)
call(root, Obf.TABLE_ROW, new Class<?>[0], cellClass);
cell = call(root, Obf.TABLE_ADD, new Class<?>[] {actorClass}, cellClass, state.status);
layoutCell(cell, Obf.CELL_LEFT, Obf.CELL_BOTTOM);
wire(loader, refresh, new Runnable() {
@Override
@@ -203,7 +208,7 @@ public final class ObjectPanel {
try {
// Table.clearChildren()(载荷名 `SourceFile()V`):把列表里的行全清掉重建。
call(state.listTable, Obf.TABLE_CLEAR_CHILDREN, new Class<?>[0], void.class);
statusRow(state, objects.size() + " scene objects"
setStatus(state, objects.size() + " scene objects"
+ (state.target == null ? "" : "; target = " + SceneObjects.kind(state.target)
+ " " + SceneObjects.nameOf(state.target)));
Class<?> cellClass = Class.forName(Obf.CELL, true, state.loader);
@@ -380,9 +385,38 @@ public final class ObjectPanel {
* 状态文字:改完布局后不再单独占一行(那会把列表挤下去),改成写日志 +
* 记在 state 里,下一次 {@link #refreshList} 会把它显示为列表区第一行。
*/
/**
* 下段的"实时提示":保留最近 {@link #LOG_LINES} 条,多行显示在底部。
* 所有 setText 都要在渲染线程上做。
*/
private static final int LOG_LINES = 6;
private static void setStatus(final State state, final String text) {
state.statusText = text;
System.err.println("[panel] " + text);
if (state.status == null) return;
synchronized (state.log) {
state.log.addLast(text);
while (state.log.size() > LOG_LINES) state.log.removeFirst();
}
final StringBuilder joined = new StringBuilder();
synchronized (state.log) {
for (String line : state.log) {
if (joined.length() > 0) joined.append('\n');
joined.append(line);
}
}
SceneActions.onEditorThread(state.loader, new Runnable() {
@Override
public void run() {
try {
call(state.status, Obf.LABEL_SET_TEXT, new Class<?>[] {CharSequence.class},
void.class, joined.toString());
} catch (Throwable error) {
System.err.println("[panel] 提示区更新失败: " + error);
}
}
});
}
/** TextField 里的文字(名字被混淆了,按"无参 + 返回 String"取)。 */