Draw the board as the canvas draws boxes, and drag cards live

The user found the board's look off from the canvas's: a block's C was
gray around a white card, borders ignored the node's style, a folded
column said nothing, and dragging felt wrong.

Columns and cards now go through the canvas's line layer, with the same
rules as Scene::add_borders: the node's border style and color, thick in
the accent color for the cursor, thick in the visual color for the
selection. A block's bracket and foot are drawn in its card's own line
and color, so the C is one shape and its joint comes out as ├, ┣ or ╠.
Tags and badges sit in the bottom border through a footer() shared with
the canvas renderer. Columns show their tags and badge too, so a folded
column says +N, and a column's title can be typed in its top border
(it wasn't shown as typed before).

A drag now moves the card live, as on the canvas (the user's pick), all
one undo step: by the row under the mouse, before a card on its top
half, after it or into its block on its bottom half, out at a foot,
first on a column's title, last below the cards. Columns keep their
widths while dragging, or a column that narrowed would slide the one
under the mouse away and the card would chase it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
skkeyeandClaude Opus 5.5 committed 2026-10-02 13:49:48 -04:00
1 parent 3716919db3
commit 38eca3c8c3
8 files changed
+424 -233

No files matched your search

+11 -11
View File
@@ -74,13 +74,7 @@ impl LineLayer {
paint: Paint,
shown: impl Fn(ScreenPos) -> bool,
) {
let stroke = match border {
Border::Rounded | Border::Square => Stroke::Solid,
Border::Double => Stroke::Double,
Border::Thick => Stroke::Thick,
Border::Dashed => Stroke::Dashed,
Border::Hidden => return,
};
let Some(stroke) = border.stroke() else { return };
if rect.width < 2 || rect.height < 2 {
return;
}
@@ -95,10 +89,8 @@ impl LineLayer {
if shown(at) {
self.add_arm(at, one, stroke, paint);
self.add_arm(at, other, stroke, paint);
if border == Border::Rounded
&& let Some(cell) = self.cell_mut(at)
{
cell.rounded = true;
if border == Border::Rounded {
self.round(at);
}
}
}
@@ -174,6 +166,14 @@ impl LineLayer {
}
}
/// Draws the light corner on a cell rounded, as a rounded box's corners
/// are.
pub fn round(&mut self, at: ScreenPos) {
if let Some(cell) = self.cell_mut(at) {
cell.rounded = true;
}
}
/// Every cell a line runs through, with its character and color.
pub fn cells(&self, glyphs: Glyphs) -> impl Iterator<Item = (ScreenPos, char, Color)> + '_ {
self.cells.iter().enumerate().filter(|(_, cell)| !cell.arms.is_empty()).map(move |(index, cell)| {