Conversation
The UI is about to let the user change how deep the treemap lays out, and re-layouts on every change. That is only smooth because of a property the layout already had without anyone writing it down: a rect's frame comes from its ancestors' sibling sizes and the area cull, never from max_depth, and the cap is tested after the rect is pushed. So the capped layout is exactly the prefix of a deeper one — changing depth dissolves deeper tiles back into their parent plate and moves nothing. Worth a test rather than a comment: the whole feature is unpleasant to use if it ever stops holding, and the assertion compares whole TreemapRects, so any field that starts depending on depth fails here first. The second test pins the other half of the semantics, that depth counts from the laid-out root. An absolute depth would leave a drilled-into folder with nothing left to show at a cap of 1.
get_treemap takes an optional maxDepth, laid out relative to root_id. Null is "as deep as the layout goes", which is the 24 that used to be hardcoded, so a caller that does not care keeps the existing picture byte for byte. The treemap has always drawn at most 24 levels; this only lets the UI ask for fewer. The clamp's floor of 1 is a contract with the UI rather than defensive programming. At a cap of 0 no rect has depth 1, and double-click, wheel and the context menu's zoom-in all hit-test `depth == 1` rects — every way into the tree but the breadcrumbs would go dead. The ceiling is what bounds the recursion and the IPC payload against a number the UI would never send itself, since the argument crosses IPC as a u32 and the layout option is a u8. Kept as a free function so it is testable without Tauri's State, the way delete_block_reason and filters_by_extension_only already are. The argument list is over clippy's limit now; the allow says why, matching lay_row's.
The treemap opened every scan fully expanded, which is a lot of pixels to read in a big folder and there was no way to ask for less. Settings now carries a Treemap depth of All, 1, 2 or 3 levels, defaulting to All so nothing changes for anyone who does not touch it. Depth is measured from the folder in view rather than from the scan root. That is what makes the setting work with the drill the treemap already had: a click fills the view with a folder and it expands one level down from there, so the setting decides how much of the *next* layer is on screen, not how deep the original scan was opened. Measured absolutely, drilling into a folder would find its own children permanently out of reach. The plate a cap stops at is painted differently, and that is the whole reason this is not a one-line layout change. Every directory plate carries a grain texture meaning "real bytes here, too small to draw"; a plate whose contents are hidden by the depth preference means something else, so it is left bare over the grain its expanded ancestors laid down and marked with a "+" in place of the texture. It has to be painted after the grain pass, not before: the grain lands on whole ancestor rects, so a bare plate drawn first would be textured right back. Both passes key off the same `depth === layoutCap(maxDepth)` test, and layoutCap mirrors the back end's clamp in one place so the plate the UI calls collapsed is the plate the layout actually stopped at. The mark is 3:1 or better against the plate in both themes — it is the only thing distinguishing a collapsed plate from dead space, so it counts as meaningful graphics, not decoration. Persisted in localStorage next to the theme. Node ids are per scan, so "remember which folders were expanded" cannot survive a rescan by id; the depth is the part of that request that can be remembered, and it is the part that caused the initial visual overload. The treemap already had the rest of the SpaceSniffer feel this was asked for — clicking a block zooms into it, the crumbs go back — so nothing about the drill or its hit-testing changed.
Li3age
marked this pull request as draft
September 19, 2026 14:17
Author
|
Superseded by #4. This branch's depth setting was reimplemented from scratch there, beside the |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2.
Adds a Treemap depth setting under Settings → View:
All / 1 / 2 / 3, defaulting toAll, so nothing changes for anyone who doesn't touch it.Depth counts from the folder in view, not from the scan root. That is what makes it work with the drill the treemap already had — click a block, the view fills with that folder, and the setting decides how much of the next layer is on screen. Measured absolutely, drilling into a folder would leave its own children permanently out of reach.
The plate a cap stops at
Every directory plate carries a grain texture that means "real bytes here, too small to draw". A plate whose contents are hidden by the depth preference means something else, so it is left bare and marked with a
+. It has to be painted after the grain pass, not before: the grain lands on whole ancestor rects, so a bare plate drawn first would be textured right back.Why changing depth does not make the map jump
A rect's frame comes from its ancestors' sibling sizes and the area cull, never from
max_depth, and the cap is tested after the rect is pushed. A capped layout is therefore exactly the prefix of a deeper one — switching depth dissolves deeper tiles back into their parent plate and moves nothing.a_depth_cap_only_hides_deeper_rectsincrates/core/src/treemap.rspins that property; it is the reason the UI does not have to freeze hit-testing while a new layout is in flight.Smaller things in here
get_treemapis over clippy's argument limit now, so it carries the sameallow(clippy::too_many_arguments)thatlay_rowalready does.+is#6b7280. The first pick was 2.04:1 against the plate, and the mark is the only thing distinguishing a collapsed plate from dead space, so it counts as a meaningful graphic rather than decoration.depth == 1, and double-click, wheel and the context menu's zoom-in all hit-testdepth == 1rects, so every way into the tree but the breadcrumbs would go dead.Heads up, unrelated to this PR
cargo clippy --workspacefails oncrates/scanner-ntfs/src/record.rs:276withclippy::chunks_exact_to_as_chunks, which is new in clippy 1.98 (-D warningsmakes it fatal). The repo doesn't pin a toolchain and CI uses@stable, so I think main is red for this too. Happy to send that fix separately if useful.