-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(#8): ✨ Made functionaliry for Accepted filtering
Created a separate panel for accepted filtering. When the button is clicked the colors of the points are either black for not accepted and white for accepted points. The panel also have a description for this.
- Loading branch information
Marie Wahlstrøm
committed
Oct 13, 2025
1 parent
4af9107
commit e2b778c
Showing
4 changed files
with
295 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| /* Accepted Filter: action button */ | ||
| #doAcceptedFilter { | ||
| display: flex; | ||
| width: 100%; | ||
| margin: 6px 0 10px; | ||
| padding: 10px 10px; | ||
| font-size: 13px; | ||
| font-weight: 500; | ||
| background-color: #3a3a3a; | ||
| color: #ffffff; | ||
| border: 1px solid #555; | ||
| border-radius: 4px; | ||
| cursor: pointer; | ||
| transition: | ||
| background-color 0.2s ease, | ||
| transform 0.1s ease; | ||
| } | ||
| #doAcceptedFilter:hover { | ||
| background-color: #505050; | ||
| } | ||
| #doAcceptedFilter:active { | ||
| transform: scale(0.97); | ||
| background-color: #606060; | ||
| } | ||
|
|
||
| /* Legend container */ | ||
| #accepted_legend { | ||
| margin-top: 10px; | ||
| padding-left: 4px; | ||
| } | ||
|
|
||
| /* Legend rows */ | ||
| #accepted_legend .legend-row { | ||
| display: flex; | ||
| align-items: center; | ||
| margin: 3px 0; | ||
| font-size: 13px; | ||
| color: #ddd; /* visible text */ | ||
| } | ||
|
|
||
| /* Color boxes */ | ||
| #accepted_legend .legend-color { | ||
| width: 16px; | ||
| height: 16px; | ||
| border: 1px solid #777; | ||
| margin-right: 8px; | ||
| border-radius: 2px; | ||
| } | ||
|
|
||
| #accepted_legend .legend-color.accepted { | ||
| background-color: #fff; | ||
| } | ||
|
|
||
| #accepted_legend .legend-color.not-accepted { | ||
| background-color: #000; | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,179 @@ | ||
| function createAcceptedPanel() { | ||
| const container = document.getElementById('accepted_list') | ||
| if (container) return | ||
|
|
||
| const menu = document.getElementById('potree_menu') | ||
| if (!menu) return | ||
|
|
||
| const header = document.createElement('h3') | ||
| header.id = 'menu_accepted' | ||
| header.innerHTML = '<span>Accepted Filter</span>' | ||
|
|
||
| const panel = document.createElement('div') | ||
| panel.className = 'pv-menu-list' | ||
| panel.innerHTML = '<div id="accepted_list" class="auto"></div>' | ||
|
|
||
| // Place above Appearance if possible (same as Elevation) | ||
| const appearance = document.getElementById('menu_appearance') | ||
| if (appearance) { | ||
| menu.insertBefore(panel, appearance) | ||
| menu.insertBefore(header, panel) | ||
| } else { | ||
| menu.appendChild(header) | ||
| menu.appendChild(panel) | ||
| } | ||
|
|
||
| if (window.$ && window.$(menu).accordion) { | ||
| try { | ||
| window.$(menu).accordion('refresh') | ||
| } catch (e) {} | ||
| } | ||
|
|
||
| // Simple toggle if accordion doesn’t manage it | ||
| header.addEventListener('click', () => { | ||
| panel.style.display = panel.style.display === 'none' ? '' : 'none' | ||
| }) | ||
| } | ||
|
|
||
| function ensureActivationButton(hooks) { | ||
| const list = document.getElementById('accepted_list') | ||
| if (!list) return | ||
| if (list.querySelector('#doAcceptedFilter')) return | ||
|
|
||
| const btn = document.createElement('button') | ||
| btn.id = 'doAcceptedFilter' | ||
| btn.type = 'button' | ||
| btn.textContent = 'Activate accepted filter' | ||
| btn.addEventListener('click', () => { | ||
| if (hooks && typeof hooks.onActivateAccepted === 'function') { | ||
| hooks.onActivateAccepted(); | ||
| } | ||
| const legend = document.getElementById('accepted_legend'); | ||
| if (legend) legend.style.display = 'block'; // ensure legend shows | ||
| }); | ||
|
|
||
| list.insertBefore(btn, list.firstChild) | ||
| } | ||
|
|
||
| function ensureAcceptedLegend() { | ||
| const list = document.getElementById('accepted_list') | ||
| if (!list) return null | ||
|
|
||
| let legend = list.querySelector('#accepted_legend') | ||
| if (!legend) { | ||
| legend = document.createElement('div') | ||
| legend.id = 'accepted_legend' | ||
| legend.style.display = 'none' // hidden until button click | ||
| legend.innerHTML = ` | ||
| <div class="legend-row"> | ||
| <div class="legend-color accepted"></div> | ||
| <span>Accepted points</span> | ||
| </div> | ||
| <div class="legend-row"> | ||
| <div class="legend-color not-accepted"></div> | ||
| <span>Not accepted points</span> | ||
| </div> | ||
| ` | ||
| list.appendChild(legend) | ||
| } | ||
| return legend | ||
| } | ||
|
|
||
| // Show/hide legend (called from viewer hook) | ||
| export function toggleAcceptedLegend(show) { | ||
| const legend = document.getElementById('accepted_legend') | ||
| if (legend) legend.style.display = show ? 'block' : 'none' | ||
| } | ||
|
|
||
| // Ensure our list wrapper exists inside the Accepted panel | ||
| function ensureAcceptedListUL() { | ||
| const host = document.getElementById('accepted_list') | ||
| if (!host) return null | ||
|
|
||
| let ul = host.querySelector('#accepted_ui') | ||
| if (!ul) { | ||
| ul = document.createElement('ul') | ||
| ul.id = 'accepted_ui' | ||
| ul.className = 'pv-menu-list' | ||
| host.appendChild(ul) | ||
| } | ||
| return ul | ||
| } | ||
|
|
||
| // Move ALL current children from Potree's extra_container into our UL | ||
| function moveAcceptedChildrenOnce() { | ||
| const source = document.querySelector('#materials\\.extra_container') | ||
| const targetUL = ensureAcceptedListUL() | ||
| if (!source || !targetUL) return false | ||
|
|
||
| // Move only the elements that should be visible in a pv-menu-list (divider + li) | ||
| const nodes = [...source.children].filter( | ||
| (n) => n.classList.contains('divider') || n.tagName.toLowerCase() === 'li' | ||
| ) | ||
|
|
||
| if (nodes.length === 0) return false | ||
|
|
||
| for (const n of nodes) { | ||
| targetUL.appendChild(n) // moving preserves event listeners | ||
| } | ||
| return true | ||
| } | ||
|
|
||
| // Observe Potree's extra_container for FUTURE children; move them as they arrive | ||
| function observeAndMirrorExtraContainer() { | ||
| const source = document.querySelector('#materials\\.extra_container') | ||
| if (!source) return null | ||
|
|
||
| const targetUL = ensureAcceptedListUL() | ||
| if (!targetUL) return null | ||
|
|
||
| const childObserver = new MutationObserver((mutations) => { | ||
| for (const m of mutations) { | ||
| if (m.type !== 'childList') | ||
| continue | ||
| // On added nodes, move any <li> or .divider into our list | ||
| ;[...m.addedNodes].forEach((node) => { | ||
| if (!(node instanceof HTMLElement)) return | ||
| const isLi = node.tagName && node.tagName.toLowerCase() === 'li' | ||
| const isDivider = node.classList && node.classList.contains('divider') | ||
| if (isLi || isDivider) { | ||
| targetUL.appendChild(node) | ||
| } | ||
| }) | ||
| } | ||
| }) | ||
|
|
||
| // Only watch direct children; Potree appends li/divider at this level | ||
| childObserver.observe(source, { childList: true }) | ||
| return childObserver | ||
| } | ||
|
|
||
| export function initAcceptedControls(viewer, hooks = {}) { | ||
| // 1) Always render panel + button | ||
| createAcceptedPanel() | ||
| ensureActivationButton(hooks) | ||
| ensureAcceptedListUL() | ||
| ensureAcceptedLegend() | ||
|
|
||
| // 2) Wait for Potree to create extra_container, then move children & keep mirroring | ||
| // const menu = | ||
| // document.getElementById('potree_menu') || | ||
| // document.getElementById('menu') || | ||
| // document.body | ||
|
|
||
| // const onceObserver = new MutationObserver(() => { | ||
| // const source = document.querySelector('#materials\\.extra_container') | ||
| // if (source) { | ||
| // // stop the "finder" observer | ||
| // onceObserver.disconnect() | ||
|
|
||
| // // Move whatever is present right now | ||
| // moveAcceptedChildrenOnce() | ||
|
|
||
| // // Keep mirroring anything Potree adds later | ||
| // observeAndMirrorExtraContainer() | ||
| // } | ||
| // }) | ||
|
|
||
| //onceObserver.observe(menu, { childList: true, subtree: true }) | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters