Skip to content

Commit

Permalink
Add documentation to selection logic
Browse files Browse the repository at this point in the history
  • Loading branch information
alexvanyo committed Dec 16, 2024
1 parent 8c7fdd9 commit 0c7d4c4
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,15 @@ fun SelectionOverlay(
}
}

val SelectionState.SelectingBox.FixedSelectingBox.initialHandles get(): List<Offset> {
/**
* Computes the initial handles for a [SelectionState.SelectingBox.FixedSelectingBox].
*
* If there is a [SelectionState.SelectingBox.FixedSelectingBox.previousTransientSelectingBox], then these handles
* will follow those offsets (to be transiently adjusted back to the rounded values).
*
* Otherwise, it will just be the direct fixed values.
*/
private val SelectionState.SelectingBox.FixedSelectingBox.initialHandles get(): List<Offset> {
val initialHandleAOffset: Offset
val initialHandleBOffset: Offset
val initialHandleCOffset: Offset
Expand Down Expand Up @@ -243,12 +251,23 @@ private fun FixedSelectingBoxOverlay(
modifier: Modifier = Modifier,
) {
Box(modifier) {
/**
* The initial handles to initialize the handles with.
*/
val initialHandles = selectionSessionState.value.initialHandles

/**
* The [DraggableAnchors2D] aligned to the current grid.
*/
val handleAnchors = remember(scaledCellPixelSize, cellWindow) {
GridDraggableAnchors2d(scaledCellPixelSize, cellWindow)
}

/**
* State holders for the value change confirmation lambdas.
*
* These are initialized with a placeholder method, since this depends on the state of the other handles.
*/
val confirmValueChangeStates = List(initialHandles.size) { index ->
key(index) {
remember { mutableStateOf({ _: IntOffset -> true }) }
Expand All @@ -257,6 +276,12 @@ private fun FixedSelectingBoxOverlay(

val coroutineScope = rememberCoroutineScope()

/**
* A list of [Animatable]s for each handle representing the fractional part of the initial handle value, in
* cell coordinates.
*
* This will be initially added to the offset calculations, and animated to zero.
*/
val transientSelectingBoxAnimatables = initialHandles.mapIndexed { index, offset ->
key(index) {
remember {
Expand All @@ -269,6 +294,7 @@ private fun FixedSelectingBoxOverlay(
}
}

// Resolve the transient offsets to zero
transientSelectingBoxAnimatables.forEachIndexed { index, animatable ->
key(index) {
LaunchedEffect(animatable) {
Expand Down Expand Up @@ -553,6 +579,9 @@ private fun TransientSelectingBoxOverlay(
}
}

/**
* A selection handle.
*/
@Composable
fun SelectionHandle(
isActive: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,30 @@ sealed interface SelectionState {

@Serializable
data class FixedSelectingBox(
/**
* The top left coordinate of the box.
*/
@Serializable(with = IntOffsetSerializer::class) val topLeft: IntOffset,
/**
* The width of the box, which may be negative.
*/
val width: Int,
/**
* The height of the box, which may be negative.
*/
val height: Int,
/**
* The previous [TransientSelectingBox] that was used to create the current [FixedSelectingBox], if any.
*/
val previousTransientSelectingBox: TransientSelectingBox?,
) : SelectingBox

@Serializable
data class TransientSelectingBox(
/**
* The [Rect] describing the transient box. This [Rect] may not be normalized, and have either a negative
* width or a negative height.
*/
@Serializable(with = RectSerializer::class) val rect: Rect,
) : SelectingBox
}
Expand Down

0 comments on commit 0c7d4c4

Please sign in to comment.