Skip to content

Add Bevel and City shading styles - #1

Merged
larsbrubaker merged 2 commits into
larsbrubaker:mainfrom
kevinepope:bevel-shading
Oct 20, 2026
Merged

larsbrubaker merged 2 commits into
larsbrubaker:mainfrom
kevinepope:bevel-shading

Conversation

@kevinepope

@kevinepope kevinepope commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Two new map styles beside Cushion and Flat: Bevel and City.

Bevel. Each file is an even fill with a two-pixel rim lightened along the top and left edges and darkened along the bottom and right, so it reads as lit from the upper left like the cushions but with hard edges. Small rectangles get a one-pixel rim, and anything under 3 px gets none.

  • render/raster.rs: Shading::Bevel with paint_bevel, plus Shading::ALL, key, from_key and label helpers (mirroring Theme).
  • Toolbar: the Cushions checkbox becomes a Cushion / Flat / Bevel segmented switch (same SHADING_ID).
  • Menus: View ▸ Cushion Shading becomes a View ▸ Shading submenu with radio items; Command::ToggleCushions becomes Command::Shading(Shading) with ids view.shading.{cushion,flat,bevel}. The macOS menu bar follows through the shared spec.
  • Settings: the style is stored as a shading key; cushions is still written so 0.1.1 reads the file unchanged, and old files with only cushions still load.
  • Docs: CHANGELOG, PLAN §3.4 and the menu list, README feature line.

City (second commit). The map as a cityscape seen from above and a little to the lower right. Every painted rectangle is a building: its footprint is the rectangle less a one-pixel street on the right and bottom, widened by 1.5 px per enclosing folder that ends on that edge (so folders read as city blocks between avenues); its height is the cube root of its size relative to the biggest item in view, up to a tenth of the raster's shorter side (8–56 px), and flat under 2 px. Buildings are drawn in an oblique projection (roof moved up one pixel and left half a pixel per pixel of height, right wall at 0.7, bottom wall at 0.5) with a per-band depth buffer, so the parallel row bands stay independent of paint order.

  • render/city.rs: Building, plan (footprints, streets, heights) and paint; raster.rs bins by the buildings' projected extents and allocates the depth buffer per band.
  • Only the pixels are 3D: hit testing, hover and the outlines still use the footprint, so a tall roof is not clickable where it overhangs.
  • Toolbar and View ▸ Shading gain a City entry; settings key cityscape.

Tests

  • New rasteriser tests: bevel_mode_has_a_light_top_left_rim_and_a_dark_bottom_right_rim and tiny_bevelled_rectangles_get_a_thin_rim_or_none (pixel invariants, same style as the cushion and flat tests).
  • City: a_cityscape_building_has_a_raised_roof_two_walls_and_a_street (one-file raster: roof offset, both walls, the street) and bigger_files_make_taller_buildings_and_streets_widen_at_folder_edges (cube-root heights, wider streets on folder edges, visible ground, nothing lit beyond a roof).
  • Settings: round trip through Bevel, and the_shading_key_wins_over_the_old_cushions_flag.
  • Menu, toolbar and native menu-bar tests updated for the three-way switch and submenu.
  • cargo test --workspace, cargo clippy --workspace --all-targets -- -D warnings and cargo fmt are green on macOS (Apple Silicon).

Bevel and City on the laptop-ssd demo drive, light theme:

Bevel shading on the demo laptop drive

City shading on the demo laptop drive

🤖 Generated with Claude Code

kevinepope and others added 2 commits October 16, 2026 17:47
…-right rim

A third map style beside Cushion and Flat. Each file is an even fill with a
two-pixel rim lightened along the top and left edges and darkened along the
bottom and right, so it reads as lit from the upper left like the cushions
but with hard edges. Small rectangles get a one-pixel rim, under 3 px none.

The toolbar's Cushions checkbox becomes a Cushion / Flat / Bevel switch and
View > Cushion Shading becomes a View > Shading submenu with radio items on
both the in-window and macOS menu bars. Settings store the style as a
`shading` key and keep writing `cushions` so 0.1.1 still reads the file.

Pixel-invariant tests cover the rims and the thin-rim fallback; menu, toolbar
and settings tests follow the new switch.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A fourth style beside Cushion, Flat and Bevel. Every painted rectangle is a
building: its footprint is the rectangle less a one-pixel street on the right
and bottom, widened by 1.5 px per enclosing folder that ends on that edge, so
folders read as city blocks between avenues; its height is the cube root of
its size relative to the biggest item in view, up to a tenth of the raster's
shorter side (8-56 px), and flat under 2 px. Buildings are drawn in an oblique
projection (roof moved up one pixel and left half a pixel per pixel of height,
right wall at 0.7, bottom wall at 0.5 brightness) with a per-band depth buffer,
so the parallel bands stay independent of paint order.

Only the pixels are 3D: hit testing, hover and the outlines still use the
footprint. The toolbar switch and View > Shading gain a City entry; settings
store it as "cityscape".

Tests: a one-file raster checks the roof offset, both walls and the street; the
fixture checks heights by cube root, wider streets on folder edges, visible
ground and that nothing is lit beyond a roof.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@kevinepope kevinepope changed the title Add Bevel shading: raised tiles with a light top-left and dark bottom-right rim Add Bevel and City shading styles Oct 17, 2026
@larsbrubaker
larsbrubaker merged commit 858908a into larsbrubaker:main Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants