package center.sciprog.maps.features import androidx.compose.ui.input.pointer.PointerEvent import androidx.compose.ui.input.pointer.isPrimaryPressed /** * @param result - the endpoint of the drag to perform constrained drag * @param handleNext - if false do not evaluate subsequent drag handles */ public data class DragResult(val result: ViewPoint, val handleNext: Boolean = true) public fun interface DragHandle { /** * @param event - qualifiers of the event used for drag * @param start - is a point where drag begins, end is a point where drag ends * @param end - end point of the drag * * @return true if default event processors should be used after this one */ public fun handle(event: PointerEvent, start: ViewPoint, end: ViewPoint): DragResult public companion object { public fun bypass(): DragHandle = DragHandle { _, _, end -> DragResult(end) } /** * Process only events with primary button pressed */ public fun withPrimaryButton( block: (event: PointerEvent, start: ViewPoint, end: ViewPoint) -> DragResult, ): DragHandle = DragHandle { event, start, end -> if (event.buttons.isPrimaryPressed) { block(event, start, end) } else { DragResult(end) } } /** * Combine several handles into one */ public fun combine(vararg handles: DragHandle): DragHandle = DragHandle { event, start, end -> var current: ViewPoint = end handles.forEach { val result = it.handle(event, start, current) if (!result.handleNext) return@DragHandle result else { current = result.result } } return@DragHandle DragResult(current) } } }