diff --git a/app/src/main/java/org/fknives/android/compose/learning/pickers/NumberPickerScreen.kt b/app/src/main/java/org/fknives/android/compose/learning/pickers/NumberPickerScreen.kt index c311968..dd95d26 100644 --- a/app/src/main/java/org/fknives/android/compose/learning/pickers/NumberPickerScreen.kt +++ b/app/src/main/java/org/fknives/android/compose/learning/pickers/NumberPickerScreen.kt @@ -31,7 +31,7 @@ fun NumberPickerScreen() { var selected by remember { mutableStateOf(0) } NumberPicker( modifier = Modifier.defaultMinSize(minWidth = 200.dp), - onSelectedChange = { + onSelectedValueChange = { selected = it }, textStyle = MaterialTheme.typography.h5, @@ -44,7 +44,7 @@ fun NumberPickerScreen() { NumberPicker( config = NumberPickerConfig.configMinutePicker, selectedValue = selected, - onSelectedChange = { selected = it }, + onSelectedValueChange = { selected = it }, roundAround = false, textStyle = MaterialTheme.typography.h5 ) @@ -55,7 +55,7 @@ fun NumberPickerScreen() { NumberPicker( config = NumberPickerConfig.configMinutePicker, selectedValue = selected, - onSelectedChange = { selected = it }, + onSelectedValueChange = { selected = it }, timePicker = { LinedInnerTextPicker(modifier = Modifier.defaultMinSize(minWidth = 200.dp)) } ) } @@ -66,7 +66,7 @@ fun NumberPickerScreen() { NumberPicker( config = NumberPickerConfig.configHourPicker24, selectedValue = selected, - onSelectedChange = { selected = it } + onSelectedValueChange = { selected = it } ) { TextPicker( modifier = Modifier.defaultMinSize(minWidth = 200.dp), @@ -88,7 +88,7 @@ fun NumberPickerScreen() { NumberPicker( config = NumberPickerConfig(maximum = 5, minimum = 1, skipInBetween = 1), selectedValue = selected, - onSelectedChange = { selected = it } + onSelectedValueChange = { selected = it } ) } } @@ -99,7 +99,7 @@ fun NumberPickerScreen() { NumberPicker( config = NumberPickerConfig(maximum = 5, minimum = 1, skipInBetween = 2), selectedValue = selected, - onSelectedChange = { selected = it } + onSelectedValueChange = { selected = it } ) } } @@ -110,7 +110,7 @@ fun NumberPickerScreen() { NumberPicker( config = NumberPickerConfig(maximum = 5, minimum = 1, skipInBetween = 1, reversedOrder = true), selectedValue = selected, - onSelectedChange = { selected = it } + onSelectedValueChange = { selected = it } ) } } @@ -122,7 +122,7 @@ fun NumberPickerScreen() { config = NumberPickerConfig(maximum = 5, minimum = 1, skipInBetween = 2, reversedOrder = true), selectedValue = selected, roundAround = false, - onSelectedChange = { selected = it }, + onSelectedValueChange = { selected = it }, ) } } diff --git a/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPicker.kt b/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPicker.kt index 631a4d4..c03158e 100644 --- a/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPicker.kt +++ b/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPicker.kt @@ -7,12 +7,29 @@ import androidx.compose.ui.text.TextStyle import org.fknives.android.compose.picker.text.TextPickerState import org.fknives.android.compose.picker.text.util.TextPickerDefaults +/** + * Configuration API around [TextPicker][org.fknives.android.compose.picker.text.TextPicker]. + * + * Sets up inner StateManagement of [TextPicker][org.fknives.android.compose.picker.text.TextPicker] in a [NumberPickerScope] + * then places it via [CustomInnerTextPicker]. + * + * @param modifier [Modifier] of [TextPicker][org.fknives.android.compose.picker.text.TextPicker] + * @param config Configuration of NumberPicker. Defines the Number Range that should be shown. + * @param selectedValue The selected value, expected to be between [config]'s minimum and maximum. + * @param onSelectedValueChange Notified when the Selected Value Changes. + * @param onIndexDifferenceChanging Signals the animation changes, how much the current dragging is away from index of [selectedValue]. + * Negative values mean the index were decreased, Positive means it was increased. + * **IMPORTANT! works with index-difference, not values (minimumValue = 0 index)** + * @param textStyle TextStyle of [TextPicker][org.fknives.android.compose.picker.text.TextPicker] + * @param roundAround roundAround of [TextPicker][org.fknives.android.compose.picker.text.TextPicker]. + * Should behave like a Wheel, or should be limited. + */ @Composable fun NumberPicker( modifier: Modifier = Modifier, config: NumberPickerConfig, selectedValue: Int, - onSelectedChange: (Int) -> Unit, + onSelectedValueChange: (Int) -> Unit, onIndexDifferenceChanging: (Int) -> Unit = TextPickerDefaults.onIndexDifferenceChanging, textStyle: TextStyle = LocalTextStyle.current, roundAround: Boolean = TextPickerDefaults.roundAround, @@ -20,7 +37,7 @@ fun NumberPicker( NumberPicker( config = config, selectedValue = selectedValue, - onSelectedChange = onSelectedChange, + onSelectedValueChange = onSelectedValueChange, onIndexDifferenceChanging = onIndexDifferenceChanging ) { CustomInnerTextPicker( @@ -31,11 +48,28 @@ fun NumberPicker( } } +/** + * Configuration API around [TextPicker][org.fknives.android.compose.picker.text.TextPicker]. + * + * Sets up inner StateManagement of [TextPicker][org.fknives.android.compose.picker.text.TextPicker] in a [NumberPickerScope] + * then places it via [timePicker]. + * + * @param config Configuration of NumberPicker. Defines the Number Range that should be shown. + * @param selectedValue The selected value, expected to be between [config]'s minimum and maximum. + * @param onSelectedValueChange Notified when the Selected Value Changes. + * @param onIndexDifferenceChanging Signals the animation changes, how much the current dragging is away from index of [selectedValue]. + * Negative values mean the index were decreased, Positive means it was increased. + * **IMPORTANT! works with index-difference, not values (minimumValue = 0 index)** + * Should behave like a Wheel, or should be limited. + * @param state TextPickerState of [TextPicker][org.fknives.android.compose.picker.text.TextPicker] + * @param timePicker The Lambda placing the TimePicker. [NumberPickerScope] is provided with the configuration setup. + * *Note: Check [StandardInnerTextPicker], [CustomInnerTextPicker], if you wish to customize.* + */ @Composable fun NumberPicker( config: NumberPickerConfig, selectedValue: Int, - onSelectedChange: (Int) -> Unit, + onSelectedValueChange: (Int) -> Unit, onIndexDifferenceChanging: (Int) -> Unit = TextPickerDefaults.onIndexDifferenceChanging, state: TextPickerState = rememberNumberPickerState(selectedValue = selectedValue, config = config), timePicker: @Composable NumberPickerScope.() -> Unit = { StandardInnerTextPicker() } @@ -46,7 +80,7 @@ fun NumberPicker( state = state, config = config, onIndexDifferenceChanging = onIndexDifferenceChanging, - onSelectedChange = onSelectedChange + onSelectedValueChange = onSelectedValueChange ) timePicker(numberPickerScope) diff --git a/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerConfig.kt b/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerConfig.kt index c98446a..704513b 100644 --- a/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerConfig.kt +++ b/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerConfig.kt @@ -2,6 +2,38 @@ package org.fknives.android.compose.picker.number import androidx.compose.runtime.Immutable +/** + * Configuration of [NumberPicker] + * + * [minimum] The minimum value shown inside the [NumberPicker]. Minimum Value included in the List of Elements. + * [maximum] The maximum value shown inside the [NumberPicker]. Maximum Value included in the List of Elements. + * [reversedOrder] false, means goes from [minimum]..[maximum], true means [maximum]..[minimum] + * [skipInBetween], number of elements skipped when going from one value to another. + * + * Example1: + * minimum = 1, maximum = 3, reversedOrder = false, skipInBetween=0 + * => + * [1,2,3] + * *Note: No skipping, no reverse, so all elements from 1 to 3* + * + * Example2: + * minimum = 1, maximum = 3, reversedOrder = true, skipInBetween=0 + * => + * [3,2,1] + * *Note: No skipping, reverse, so all elements from 3 to 1* + * + * Example3: + * minimum = 1, maximum = 5, reversedOrder = false, skipInBetween=1 + * => + * [1,3,5] + * *Note: Skipping 1 element, no reverse, so starting from 1. Then skipping 2, so 3. Then skipping 4 so 5.* + * + * Example4: + * minimum = 1, maximum = 5, reversedOrder = true, skipInBetween=2 + * => + * [5,2] + * *Note: Skipping 2 element, Reverse, so starting from 5. Then skipping 4 and 3, so 2. Next would be smaller than minimal so, that's it.* + */ @Immutable data class NumberPickerConfig( val maximum: Int, diff --git a/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerScope.kt b/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerScope.kt index 4a80bb9..ffbd95b 100644 --- a/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerScope.kt +++ b/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerScope.kt @@ -6,6 +6,36 @@ import androidx.compose.runtime.remember import org.fknives.android.compose.picker.text.util.TextPickerDefaults import org.fknives.android.compose.picker.text.TextPickerState +/** + * Prepared parameters for [TextPicker][org.fknives.android.compose.picker.text.TextPicker]. + * + * [state] The [TextPickerState] expected to be set to [TextPicker][org.fknives.android.compose.picker.text.TextPicker] + * + * [onIndexDifferenceChanging] The onIndexDifferenceChanging Listener expected to be set to + * [TextPicker][org.fknives.android.compose.picker.text.TextPicker] + * + * [onSelectedIndexChange] The onSelectedIndexChange Listener expected to be set to + * [TextPicker][org.fknives.android.compose.picker.text.TextPicker] + * + * [textForIndex] The IndexToNumberVlaue Converter expected to be set to [TextPicker][org.fknives.android.compose.picker.text.TextPicker] + * + * [selectedIndex] The selectedIndex expected to be set to [TextPicker][org.fknives.android.compose.picker.text.TextPicker] + * + * [itemCount] The selectedIndex expected to be set to [TextPicker][org.fknives.android.compose.picker.text.TextPicker] + */ +@Immutable +interface NumberPickerScope { + val state: TextPickerState + val onIndexDifferenceChanging: (Int) -> Unit + val onSelectedIndexChange: (Int) -> Unit + val textForIndex: (Int) -> String + val selectedIndex: Int get() = state.selected + val itemCount: Int get() = state.itemCount +} + +/** + * Data class implementation of [NumberPickerScope] + */ @Immutable data class NumberPickerScopeImpl( override val state: TextPickerState, @@ -17,11 +47,20 @@ data class NumberPickerScopeImpl( override val itemCount: Int get() = state.itemCount } +/** + * Caching function, preparing the [NumberPickerScope] from simple parameters. + * + * @param state The [TextPickerState] expected to be set to [TextPicker][org.fknives.android.compose.picker.text.TextPicker] + * @param config The NumberPickers config. Used to convert between TextPicker's Index and NumberPicker's values. + * @param onSelectedValueChange NumberPicker's onSelectedValueChange Listener + * @param onIndexDifferenceChanging NumberPicker's onIndexDifferenceChanging Listener + * @param keys any additional keys, to signal changing of the scope cache. + */ @Composable fun rememberNumberPickerScope( state: TextPickerState, config: NumberPickerConfig, - onSelectedChange: (Int) -> Unit, + onSelectedValueChange: (Int) -> Unit, onIndexDifferenceChanging: (Int) -> Unit = TextPickerDefaults.onIndexDifferenceChanging, vararg keys: Any? ): NumberPickerScope { @@ -34,18 +73,8 @@ fun rememberNumberPickerScope( textForIndex = { "${indexToNumber(it)}" }, onIndexDifferenceChanging = onIndexDifferenceChanging, onSelectedIndexChange = { - onSelectedChange(indexToNumber(it)) + onSelectedValueChange(indexToNumber(it)) } ) } -} - -@Immutable -interface NumberPickerScope { - val state: TextPickerState - val onIndexDifferenceChanging: (Int) -> Unit - val onSelectedIndexChange: (Int) -> Unit - val textForIndex: (Int) -> String - val selectedIndex: Int get() = state.selected - val itemCount: Int get() = state.itemCount } \ No newline at end of file diff --git a/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerScopeExtension.kt b/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerScopeExtension.kt index ba9a0b0..6d4db9f 100644 --- a/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerScopeExtension.kt +++ b/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerScopeExtension.kt @@ -8,6 +8,12 @@ import org.fknives.android.compose.picker.text.LinedTextPicker import org.fknives.android.compose.picker.text.TextPicker import org.fknives.android.compose.picker.text.util.TextPickerDefaults +/** + * Custom [TextPicker] Creator for [NumberPicker], containing all styling [TextPicker]. + * Keeps all the default values of [TextPicker]. + * + * For More Customization, Give your Custom TextPicker callback to [NumberPicker] + */ @Composable fun NumberPickerScope.CustomInnerTextPicker( modifier: Modifier = Modifier, @@ -27,6 +33,10 @@ fun NumberPickerScope.CustomInnerTextPicker( ) } +/** + * Default [TextPicker] Creator for [NumberPicker]. + * Keeps all the default values of [TextPicker]. + */ @Composable fun NumberPickerScope.StandardInnerTextPicker(modifier: Modifier = Modifier) { TextPicker( @@ -40,6 +50,10 @@ fun NumberPickerScope.StandardInnerTextPicker(modifier: Modifier = Modifier) { ) } +/** + * Default [LinedTextPicker] Creator for [NumberPicker]. + * Keeps all the default values of [LinedTextPicker]. + */ @Composable fun NumberPickerScope.LinedInnerTextPicker(modifier: Modifier = Modifier) { LinedTextPicker( diff --git a/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerStateHelper.kt b/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerStateHelper.kt index 0f45266..73bd6c2 100644 --- a/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerStateHelper.kt +++ b/picker/src/main/java/org/fknives/android/compose/picker/number/NumberPickerStateHelper.kt @@ -5,7 +5,11 @@ import androidx.compose.runtime.remember import org.fknives.android.compose.picker.text.TextPickerState import org.fknives.android.compose.picker.text.util.rememberTextPickerState - +/** + * Caches function converting from TextPicker's Index to NumberPicker's NumberValues, defined by [config] + * + * Inverse of [valueToIndex] + */ @Composable fun rememberNumberPickerIndexToNumber(config: NumberPickerConfig): (Int) -> Int = remember(config) { @@ -20,6 +24,11 @@ fun rememberNumberPickerIndexToNumber(config: NumberPickerConfig): (Int) -> Int } } +/** + * Function converting from NumberPicker's NumberValues to TextPicker's Index, defined by [config]. + * + * Inverse of [valueToIndex] + */ private fun valueToIndex(config: NumberPickerConfig, value: Int): Int = if (config.reversedOrder) { (config.maximum - value) / (config.skipInBetween + 1) @@ -27,6 +36,9 @@ private fun valueToIndex(config: NumberPickerConfig, value: Int): Int = (value - config.minimum) / (config.skipInBetween + 1) } +/** + * Caches [TextPickerState] created from the NumberPicker's [config] and [selectedValue]. + */ @Composable fun rememberNumberPickerState(selectedValue: Int, config: NumberPickerConfig): TextPickerState { val selected = valueToIndex(value = selectedValue, config = config) diff --git a/picker/src/main/java/org/fknives/android/compose/picker/text/TextPicker.kt b/picker/src/main/java/org/fknives/android/compose/picker/text/TextPicker.kt index f00887f..b57486c 100644 --- a/picker/src/main/java/org/fknives/android/compose/picker/text/TextPicker.kt +++ b/picker/src/main/java/org/fknives/android/compose/picker/text/TextPicker.kt @@ -44,6 +44,7 @@ import org.fknives.android.compose.picker.text.util.rememberSafeTextForIndex * Setting this to False, means the first element has no elements above it, and the last element has no element below it. * @param onIndexDifferenceChanging Signals the animation changes, how much the current dragging is away from [selectedIndex]. * Negative values mean the index were decreased, Positive means it was increased. + * **IMPORTANT! works with index-difference, not index** * @param state Animation State for the TextPicker * @param animator Uses state to Animate the Composable elements. Handles continous drag, calculating fling and snapping to an index. * @param textPickerContent The actual Composables inside the TextPicker, by default it is the 4 Texts diff --git a/picker/src/main/java/org/fknives/android/compose/picker/time/TimePicker.kt b/picker/src/main/java/org/fknives/android/compose/picker/time/TimePicker.kt index 4bc5303..49bea71 100644 --- a/picker/src/main/java/org/fknives/android/compose/picker/time/TimePicker.kt +++ b/picker/src/main/java/org/fknives/android/compose/picker/time/TimePicker.kt @@ -21,7 +21,7 @@ fun TimePicker( val hourScope = rememberNumberPickerScope( state = hourState, config = hourConfig, - onSelectedChange = { + onSelectedValueChange = { onSelectedTimeChanged(selectedTime.copy(hour = it)) } ) @@ -31,7 +31,7 @@ fun TimePicker( val minuteScope = rememberNumberPickerScope( state = minuteState, config = minuteConfig, - onSelectedChange = { + onSelectedValueChange = { onSelectedTimeChanged(selectedTime.copy(minute = it)) } ) diff --git a/picker/src/main/java/org/fknives/android/compose/picker/time/clock/ClockPicker.kt b/picker/src/main/java/org/fknives/android/compose/picker/time/clock/ClockPicker.kt index 6226f77..0eac8b3 100644 --- a/picker/src/main/java/org/fknives/android/compose/picker/time/clock/ClockPicker.kt +++ b/picker/src/main/java/org/fknives/android/compose/picker/time/clock/ClockPicker.kt @@ -43,7 +43,7 @@ fun ClockTimePicker( changingIsAM = isAMResultByHourLapsCounter(lapsCounter, selectedTime.isAM) } }, - onSelectedChange = { + onSelectedValueChange = { onSelectedTimeChanged(selectedTime.copy(hour = it, isAM = changingIsAM)) }, keys = arrayOf(changingHour, hoursLapCounterByIndex, changingIsAM) @@ -66,7 +66,7 @@ fun ClockTimePicker( changingIsAM = isAMResultByHourLapsCounter(lapsCounter, selectedTime.isAM) changingHour = hourDifference }, - onSelectedChange = { + onSelectedValueChange = { onSelectedTimeChanged(selectedTime.copy(hour = selectedTime.hour + changingHour, minute = it, isAM = changingIsAM)) }, keys = arrayOf(changingHour, hoursLapCounterByIndex, changingIsAM)