Add layout review multi-select controls
This commit is contained in:
parent
4dcb6ebd0e
commit
1e55035f09
|
|
@ -5,6 +5,10 @@
|
||||||
box-shadow: 0 0 0 4px rgba(34, 197, 94, 0.18) !important;
|
box-shadow: 0 0 0 4px rgba(34, 197, 94, 0.18) !important;
|
||||||
font-weight: 800 !important;
|
font-weight: 800 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.layout-multi-select-active #layout-word-popover {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
@ -1926,6 +1930,9 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||||
<div class="word-ribbon-group">
|
<div class="word-ribbon-group">
|
||||||
<div class="word-ribbon-row">
|
<div class="word-ribbon-row">
|
||||||
<button type="button" class="layout-tool-btn active" id="layout-tool-select">Select</button>
|
<button type="button" class="layout-tool-btn active" id="layout-tool-select">Select</button>
|
||||||
|
<button type="button" class="layout-tool-btn" id="layout-select-all">Select All</button>
|
||||||
|
<button type="button" class="layout-tool-btn" id="layout-multi-select">Multi</button>
|
||||||
|
<button type="button" class="layout-tool-btn" id="layout-clear-selection">Clear</button>
|
||||||
<button type="button" class="layout-tool-btn" id="layout-tool-pan">Pan</button>
|
<button type="button" class="layout-tool-btn" id="layout-tool-pan">Pan</button>
|
||||||
<button type="button" class="layout-tool-btn" id="layout-tool-add">Add</button>
|
<button type="button" class="layout-tool-btn" id="layout-tool-add">Add</button>
|
||||||
<button type="button" class="layout-tool-btn danger" id="layout-delete-word">Delete</button>
|
<button type="button" class="layout-tool-btn danger" id="layout-delete-word">Delete</button>
|
||||||
|
|
@ -2504,6 +2511,8 @@ const HANDLE_SIZE_PX = 14;
|
||||||
const page = pages[0];
|
const page = pages[0];
|
||||||
let words = JSON.parse(JSON.stringify(page.words || []));
|
let words = JSON.parse(JSON.stringify(page.words || []));
|
||||||
let selectedId = null;
|
let selectedId = null;
|
||||||
|
let selectedIds = new Set();
|
||||||
|
let multiSelectMode = false;
|
||||||
let tool = "select";
|
let tool = "select";
|
||||||
let zoom = 1;
|
let zoom = 1;
|
||||||
let dragState = null;
|
let dragState = null;
|
||||||
|
|
@ -3070,7 +3079,7 @@ function refreshSelectionUI(opts = {}) {
|
||||||
const y2 = bbox[3] * scaleY;
|
const y2 = bbox[3] * scaleY;
|
||||||
const w = Math.max(1, x2 - x1);
|
const w = Math.max(1, x2 - x1);
|
||||||
const h = Math.max(1, y2 - y1);
|
const h = Math.max(1, y2 - y1);
|
||||||
const selected = String(word.id) === String(selectedId);
|
const selected = selectedIds.has(String(word.id)) || String(word.id) === String(selectedId);
|
||||||
|
|
||||||
if (showText) {
|
if (showText) {
|
||||||
drawReplicaText(word, bbox, x1, y1, x2, y2, w, h, scaleX, scaleY);
|
drawReplicaText(word, bbox, x1, y1, x2, y2, w, h, scaleX, scaleY);
|
||||||
|
|
@ -3558,6 +3567,7 @@ function refreshSelectionUI(opts = {}) {
|
||||||
if (popoverEl) popoverEl.style.display = "none";
|
if (popoverEl) popoverEl.style.display = "none";
|
||||||
canvas.style.cursor = "default";
|
canvas.style.cursor = "default";
|
||||||
refreshSelectionUI({ forceText: true });
|
refreshSelectionUI({ forceText: true });
|
||||||
|
if (multiSelectMode) hidePopover();
|
||||||
renderCanvas();
|
renderCanvas();
|
||||||
setStatus("No selection");
|
setStatus("No selection");
|
||||||
return;
|
return;
|
||||||
|
|
@ -3727,6 +3737,28 @@ function refreshSelectionUI(opts = {}) {
|
||||||
document.getElementById("layout-nudge-down")?.addEventListener("click", () => nudge(0, 1));
|
document.getElementById("layout-nudge-down")?.addEventListener("click", () => nudge(0, 1));
|
||||||
|
|
||||||
document.getElementById("layout-tool-select")?.addEventListener("click", () => setTool("select"));
|
document.getElementById("layout-tool-select")?.addEventListener("click", () => setTool("select"));
|
||||||
|
document.getElementById("layout-select-all")?.addEventListener("click", () => {
|
||||||
|
selectedIds = new Set(words.map(w => String(w.id)));
|
||||||
|
selectedId = Array.from(selectedIds).at(-1) || null;
|
||||||
|
refreshSelectionUI({ forceText: true });
|
||||||
|
if (multiSelectMode) hidePopover();
|
||||||
|
renderCanvas();
|
||||||
|
setStatus("Selected all: " + selectedIds.size);
|
||||||
|
});
|
||||||
|
document.getElementById("layout-clear-selection")?.addEventListener("click", () => {
|
||||||
|
selectedIds.clear();
|
||||||
|
selectedId = null;
|
||||||
|
refreshSelectionUI({ forceText: true });
|
||||||
|
renderCanvas();
|
||||||
|
setStatus("Selection cleared");
|
||||||
|
});
|
||||||
|
document.getElementById("layout-multi-select")?.addEventListener("click", () => {
|
||||||
|
multiSelectMode = !multiSelectMode;
|
||||||
|
document.getElementById("layout-multi-select")?.classList.toggle("active", multiSelectMode);
|
||||||
|
document.body.classList.toggle("layout-multi-select-active", multiSelectMode);
|
||||||
|
if (multiSelectMode) hidePopover();
|
||||||
|
setStatus(multiSelectMode ? "Multi-select on" : "Multi-select off");
|
||||||
|
});
|
||||||
document.getElementById("layout-tool-pan")?.addEventListener("click", () => setTool("pan"));
|
document.getElementById("layout-tool-pan")?.addEventListener("click", () => setTool("pan"));
|
||||||
document.getElementById("layout-tool-add")?.addEventListener("click", () => setTool("add"));
|
document.getElementById("layout-tool-add")?.addEventListener("click", () => setTool("add"));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue