diff --git a/viewpanel/src/com/spineview/ObjectPanel.java b/viewpanel/src/com/spineview/ObjectPanel.java index e8adfd7..e3179e4 100644 --- a/viewpanel/src/com/spineview/ObjectPanel.java +++ b/viewpanel/src/com/spineview/ObjectPanel.java @@ -47,6 +47,8 @@ public final class ObjectPanel { java.lang.reflect.Field fieldTarget; // 被点选的字段(可写值) Object fieldOwner; java.util.List inspectFields = new ArrayList(); + int page; // 当前页(每页 PAGE_SIZE 行) + Runnable lastRender; // 上一次渲染(翻页时重跑) List objects = new ArrayList(); Object target; } @@ -100,9 +102,12 @@ public final class ObjectPanel { Object rename = button(loader, skin, "Rename"); Object inspect = button(loader, skin, "Inspect"); Object setValue = button(loader, skin, "Set Value"); + Object prev = button(loader, skin, "Prev"); + Object next = button(loader, skin, "Next"); // 按钮直接放进根表格:两行按钮 + 一行滚动列表(与阶段四验证过的结构一致) - Object[] top = {refresh, newBone, newSlot, newBBox, newPath, delete, rename, inspect, setValue}; + Object[] top = {refresh, newBone, newSlot, newBBox, newPath, delete, rename, inspect, setValue, + prev, next}; for (int i = 0; i < top.length; i++) { Object cell = call(root, Obf.TABLE_ADD, new Class[] {actorClass}, cellClass, top[i]); layoutCell(cell, Obf.CELL_LEFT); @@ -147,6 +152,22 @@ public final class ObjectPanel { create(state, "Path"); } }); + wire(loader, prev, new Runnable() { + @Override + public void run() { + state.page--; + if (state.lastRender != null) state.lastRender.run(); + setStatus(state, "page " + (state.page + 1)); + } + }); + wire(loader, next, new Runnable() { + @Override + public void run() { + state.page++; + if (state.lastRender != null) state.lastRender.run(); + setStatus(state, "page " + (state.page + 1)); + } + }); wire(loader, setValue, new Runnable() { @Override public void run() { @@ -217,6 +238,8 @@ public final class ObjectPanel { } private static final String LOG_SEPARATOR = "---------- log ----------"; + /** 每页显示多少行 —— 不再依赖 ScrollPane 滚动(复用它时高度不重算,滚不动),改成翻页。 */ + private static final int PAGE_SIZE = 12; /** 在内容表格末尾追加"日志块"(分隔行 + 最近几条消息)。 */ private static void appendLogRows(State state) { @@ -241,6 +264,16 @@ public final class ObjectPanel { } } + /** 分页切片:只取当前页那一段。 */ + private static int[] pageRange(int total, State state) { + int pages = Math.max(1, (total + PAGE_SIZE - 1) / PAGE_SIZE); + if (state.page >= pages) state.page = pages - 1; + if (state.page < 0) state.page = 0; + int from = state.page * PAGE_SIZE; + int to = Math.min(total, from + PAGE_SIZE); + return new int[] {from, to, pages}; + } + /** 状态文字:作为列表区的第一行显示(这样不再单独占根表格的一行,布局更稳)。 */ private static void statusRow(final State state, final String text) { try { @@ -258,6 +291,13 @@ public final class ObjectPanel { /** 重新读一遍树、重建对象列表(全部在编辑器渲染线程上做)。 */ private static void refreshList(final State state) { + final State st = state; + state.lastRender = new Runnable() { + @Override + public void run() { + refreshList(st); + } + }; SceneActions.onEditorThread(state.loader, new Runnable() { @Override public void run() { @@ -276,7 +316,8 @@ public final class ObjectPanel { state.logBlockStarted = false; Class cellClass = Class.forName(Obf.CELL, true, state.loader); Class actorClass = Class.forName(Obf.ACTOR, true, state.loader); - for (int i = 0; i < objects.size() && i < 300; i++) { + int[] range = pageRange(Math.min(objects.size(), 300), state); + for (int i = range[0]; i < range[1]; i++) { final Object object = objects.get(i); Object row = button(state.loader, state.skin, SceneObjects.kind(object) + " " + SceneObjects.nameOf(object)); @@ -340,6 +381,13 @@ public final class ObjectPanel { * 字段名是被混淆的(一堆 D/B/L),所以每行都带上类型;对象引用只显示类名。 */ private static void inspect(final State state) { + final State st = state; + state.lastRender = new Runnable() { + @Override + public void run() { + inspect(st); + } + }; SceneActions.onEditorThread(state.loader, new Runnable() { @Override public void run() { @@ -359,6 +407,7 @@ public final class ObjectPanel { new java.util.HashMap(); lines.add("selected: " + SceneObjects.kind(object) + " \"" + SceneObjects.nameOf(object) + "\" (" + object.getClass().getName() + ")"); + if (object != state.inspected) state.page = 0; state.inspected = object; state.fieldTarget = null; lines.add("--- fields (" + countFields(object) + ") --- (点一行字段可改值)"); @@ -466,6 +515,7 @@ public final class ObjectPanel { Object current = SceneObjects.selected(state.loader); if (current != null && current != last) { last = current; + state.page = 0; inspect(state); } Thread.sleep(600); @@ -532,7 +582,8 @@ public final class ObjectPanel { state.logBlockStarted = false; Class cellClass = Class.forName(Obf.CELL, true, state.loader); Class actorClass = Class.forName(Obf.ACTOR, true, state.loader); - for (int i = 0; i < lines.size(); i++) { + int[] range = pageRange(lines.size(), state); + for (int i = range[0]; i < range[1]; i++) { final Object[] target = clickable.get(Integer.valueOf(i)); Object row = button(state.loader, state.skin, lines.get(i)); Object cell = call(state.listTable, Obf.TABLE_ADD, new Class[] {actorClass},