Improve Android app UI and controller flows

This commit is contained in:
2026-10-09 16:43:58 +08:00
parent c0e26b97fe
commit 608229a497
90 changed files with 8103 additions and 1133 deletions
@@ -12,6 +12,7 @@ import {
deleteTextElement,
duplicateTextElement,
getScene,
getSelectedLayer,
getSelectedTextElement,
selectTextElement,
subscribeScene,
@@ -116,7 +117,7 @@ function displayName(element, index) {
}
function renderElementList(scene, selectedId) {
const items = scene.elements.map((element, index) => {
const items = (getSelectedLayer().elements||[]).map((element, index) => {
const button = document.createElement("button");
button.type = "button";
button.className = "text-element-item";
@@ -144,7 +145,7 @@ function renderSelection({ scene, selectedTextId, reason }) {
selectionStatus.textContent = selected
? `已选中“${selected.text || "空文字"}” · 可在画板拖动,拖右下角控制点等比缩放`
: "请先新建或选择一个文字元素;也可点击画板中文字或从列表选择。";
const shouldRefreshFields = renderedSelectionId !== selectedTextId
const shouldRefreshFields = reason === "selection" || reason === "undo" || reason === "move-cancel" || reason === "layer-move" || renderedSelectionId !== selectedTextId
|| ["subscribe", "selection", "create", "duplicate", "delete", "gesture"].includes(reason);
if (shouldRefreshFields) applyElementToFields(selected);
}
@@ -169,12 +170,28 @@ function formPatch(element) {
form.addEventListener("input", (event) => {
if (event.target === fontInput || event.target === fontFileInput) return;
if (["text-x", "text-y"].includes(event.target.id)) return;
if (suppressForm) return;
const selected = getSelectedTextElement();
if (!selected) return;
updateTextElement(selected.id, formPatch(selected), "form");
const patch = formPatch(selected);
delete patch.x;
delete patch.y;
updateTextElement(selected.id, patch, "form");
});
for (const id of ["text-x", "text-y"]) {
field(id).addEventListener("change", () => {
const selected = getSelectedTextElement();
if (selected) updateTextElement(selected.id, {
x: numericValue("text-x", selected.x), y: numericValue("text-y", selected.y),
}, "gesture");
});
field(id).addEventListener("keydown", event => {
if (event.key === "Enter") { event.preventDefault(); field(id).blur(); }
});
}
document.getElementById("create-text").addEventListener("click", () => {
const created = addTextElement({
text: "ok",
@@ -332,18 +349,10 @@ async function initializeTextWorkspace() {
}
}
if (!getSelectedTextElement()) {
const topmost = getScene().elements.at(-1);
const topmost = getSelectedLayer().elements?.at(-1);
if (topmost) selectTextElement(topmost.id);
else applyElementToFields(null);
}
}
registerWorkspace({
id: "text",
title: "文字显示",
elementId: "workspace-text",
order: 40,
persistence: "local",
capabilities: ["scene-template-save"],
onEnter: initializeTextWorkspace,
});
export { initializeTextWorkspace };