Card drag preview renders at the source face's laid-out width
The replica framed to a font-derived nominal width, so faces in wide lanes' interior masonry columns and narrow lanes dragged a preview of the wrong size and the cursor could sit over empty space beside it. CardFaceView's existing onGeometryChange now reports size, not height alone - height still feeds LaneDropRegistry, width feeds the replica - and BoardMetrics.cardReplicaWidth(measured:bodyPointSize:) keeps the old figure as the documented not-yet-laid-out fallback. Same row, same paddings, same lineLimit at the same width means the same height, so the preview is now an exact overlay of the face it left. Manual verification pending alongside the lane grab-point card: 3x vs 1x lanes, interior masonry columns, window re-divide, trash rows, large text sizes, drag-at-creation fallback. 3 tests. 1661 green on both schemes. Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -164,8 +164,24 @@ enum BoardMetrics {
|
||||
|
||||
// MARK: - The drag replica
|
||||
|
||||
/// The width the card drag's replica is drawn at — a card at a representative lane width, since
|
||||
/// the image under the cursor has no lane to measure itself against.
|
||||
/// The width the card drag's replica is drawn at: **the width of the face it was lifted from**.
|
||||
///
|
||||
/// A face is as wide as the interior masonry column it sits in — a function of its lane's slot
|
||||
/// width and its lane's column count (`LaneLayoutMath`, `MasonryLayout`) — so it is not a figure
|
||||
/// this file can derive at all, only one the live face can report (`CardFaceView` measures it
|
||||
/// alongside the height the drop model already takes). Drawn at anything else, the image under
|
||||
/// the cursor is a card the board does not contain, and the pointer sits beside it rather than on
|
||||
/// it.
|
||||
///
|
||||
/// `measured` is that width, and the fallback below is for the face that has not reported one
|
||||
/// yet.
|
||||
static func cardReplicaWidth(measured: CGFloat, bodyPointSize: CGFloat) -> CGFloat {
|
||||
guard measured.isFinite, measured > 0 else { return cardReplicaWidth(bodyPointSize: bodyPointSize) }
|
||||
return measured
|
||||
}
|
||||
|
||||
/// The replica's fallback width — a card at a representative lane width, for the face that has
|
||||
/// not laid out yet and so has no width of its own to give.
|
||||
static func cardReplicaWidth(bodyPointSize: CGFloat) -> CGFloat {
|
||||
em(17, bodyPointSize: bodyPointSize)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user