Skip to content

Commit

Permalink
feat(#4): 📝 add possibility to rename the title of a saved position f…
Browse files Browse the repository at this point in the history
…rom the sidebar

it is now possible to double-click on a saved position's name to rename it. The update is cascaded to the live-scene elements
  • Loading branch information
franmagn committed Oct 14, 2025
1 parent 1634ea8 commit 94a7959
Showing 1 changed file with 91 additions and 10 deletions.
101 changes: 91 additions & 10 deletions src/AnnotationControl/annotationPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ export function initAnnotationsPanel(viewer) {
return null
}
// Monotonic numbering: assign an increasing number to each UUID and never reuse numbers.
// Stored in-memory for the session; later we can persist to a file.
const _uuidToIndex = new Map()
let _nextIndex = 1

Expand Down Expand Up @@ -114,7 +113,7 @@ export function initAnnotationsPanel(viewer) {
for (const a of coll) {
if (!a) continue
if (a.uuid === uuid || (a.data && a.data.uuid === uuid)) return a
}
}
} catch (e) {
// fallback
try {
Expand Down Expand Up @@ -161,7 +160,6 @@ export function initAnnotationsPanel(viewer) {
if (live) {
if (typeof live.title !== 'undefined') live.title = newName
if (typeof live.name !== 'undefined') live.name = newName
// for Potree Annotation object, data.title or similar may be used
if (live.data) live.data.title = newName
}
} catch (e) {
Expand All @@ -170,18 +168,29 @@ export function initAnnotationsPanel(viewer) {
}
}
} catch (e) {
// ignore failures; we just won't rename nodes in that case
// ignore failures
}

// Build list entries for each annotation node
annotationsRoot.children.forEach((node) => {
// Build list entries for each annotation node
annotationsRoot.children.forEach((node) => {

const row = document.createElement('div')
row.className = 'annotation-row'

const label = document.createElement('span')
label.textContent = node.text || 'Unnamed'
const label = document.createElement('span')
label.textContent = node.text || 'Unnamed'
label.className = 'annotation-label'
// attach uuid for editing
try {
const uuid = (node.data && node.data.uuid) || null
if (uuid) label.dataset.uuid = uuid
} catch (e) {}
// double-click label to edit
label.addEventListener('dblclick', (ev) => {
ev.stopPropagation()
const uuid = label.dataset.uuid
if (uuid) startInlineEditForUUID(uuid)
})

// Jump button

Expand Down Expand Up @@ -209,7 +218,7 @@ export function initAnnotationsPanel(viewer) {
annPos ||
vecToArray(ann.cameraTarget) ||
viewer.scene.view.getPivot()
viewer.scene.view.setView(camPos, target, 4000)
viewer.scene.view.setView(camPos, target, 4000) //animation duration in ms
}
}
row.appendChild(jumpBtn)
Expand Down Expand Up @@ -276,7 +285,7 @@ export function initAnnotationsPanel(viewer) {

row.appendChild(label)
row.appendChild(delBtn)
// show saved camera info if present
// show saved camera and point info
try {
const ann = node.data || {}

Expand Down Expand Up @@ -308,6 +317,78 @@ export function initAnnotationsPanel(viewer) {
})
}

// Start inline editing for a given annotation UUID (opens an input in the sidebar)
function startInlineEditForUUID(uuid) {
if (!uuid) return
// find the row label element
const labelEl = targetContainer.querySelector(`.annotation-label[data-uuid="${uuid}"]`)
if (!labelEl) return
const oldText = labelEl.textContent || ''
const input = document.createElement('input')
input.type = 'text'
input.value = oldText
input.className = 'annotation-edit-input'
labelEl.replaceWith(input)
input.focus()
input.select()

function finish(commit) {
const newText = commit ? input.value.trim() || oldText : oldText
// restore label
const newLabel = document.createElement('span')
newLabel.className = 'annotation-label'
newLabel.textContent = newText
newLabel.dataset.uuid = uuid
newLabel.addEventListener('dblclick', (ev) => {
ev.stopPropagation()
startInlineEditForUUID(uuid)
})
input.replaceWith(newLabel)
// commit to jsTree and live annotation
_commitEditedName(uuid, newText)
}

input.addEventListener('blur', () => finish(true))
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
finish(true)
} else if (e.key === 'Escape') {
finish(false)
}
})
}

function _commitEditedName(uuid, name) {
if (!uuid) return
// update jsTree node text
try {
const tree = $('#jstree_scene').jstree && $('#jstree_scene').jstree()
if (tree) {
const annotationsRoot = tree.get_json('annotations')
if (annotationsRoot && annotationsRoot.children) {
const node = annotationsRoot.children.find((c) => (c.data && c.data.uuid) === uuid)
if (node) {
_renameJSTreeNode(node.id, name)
node.text = name
}
}
}
} catch (e) {}

// update live annotation
try {
const live = _findLiveAnnotationByUUID(uuid)
if (live) {
if (typeof live.title !== 'undefined') live.title = name
if (typeof live.name !== 'undefined') live.name = name
if (live.data) live.data.title = name
}
} catch (e) {}

// refresh sidebar to reflect changes
setTimeout(updateAnnotationsList, 0)
}

// Add Annotation UI (mimics Potree toolbar/pinpoint-button logic)
function createAddButton() {
const btn = document.createElement('button')
Expand Down

0 comments on commit 94a7959

Please sign in to comment.