Skip to content
This repository has been archived by the owner on Mar 18, 2024. It is now read-only.

Commit

Permalink
Add rpe picker to keyboard
Browse files Browse the repository at this point in the history
  • Loading branch information
AnkitSuda committed Nov 15, 2022
1 parent c7199a7 commit 54dc5ae
Show file tree
Hide file tree
Showing 7 changed files with 368 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -367,13 +367,13 @@ private fun LazyItemScope.SetItem(
mutableStateOf(exerciseLogEntry)
}

LaunchedEffect(key1 = exerciseLogEntry) {
// We have to change saved rpe manually because
// main rpe change is not handled by SetItem function
if (exerciseLogEntry.rpe != mLogEntry.rpe) {
mLogEntry = mLogEntry.copy(rpe = exerciseLogEntry.rpe)
}
}
// LaunchedEffect(key1 = exerciseLogEntry) {
// // We have to change saved rpe manually because
// // main rpe change is not handled by SetItem function
// if (exerciseLogEntry.rpe != mLogEntry.rpe) {
// mLogEntry = mLogEntry.copy(rpe = exerciseLogEntry.rpe)
// }
// }

val completionAnimDuration = 200
val completionAnimSpecFloat =
Expand Down Expand Up @@ -488,6 +488,9 @@ private fun LazyItemScope.SetItem(
onSetTypeChange = { _, value ->
handleOnChange(mLogEntry.copy(setType = value))
},
onRpeChange = { _, value ->
handleOnChange(mLogEntry.copy(rpe = value))
},
onRequestRpeSelector = onRequestRpeSelector
)
}
Expand All @@ -507,6 +510,7 @@ private fun SetItemLayout(
onTimeChange: (ExerciseLogEntry, Long?) -> Unit,
onCompleteChange: (ExerciseLogEntry, Boolean) -> Unit,
onSetTypeChange: (ExerciseLogEntry, LogSetType) -> Unit,
onRpeChange: (ExerciseLogEntry, Float?) -> Unit,
onRequestRpeSelector: (ExerciseLogEntry) -> Unit,
) {
val typeOfSet = exerciseLogEntry.setType ?: LogSetType.NORMAL
Expand Down Expand Up @@ -649,27 +653,36 @@ private fun SetItemLayout(
if (exercise.category == ExerciseCategory.WEIGHTS_AND_REPS
|| exercise.category == ExerciseCategory.REPS
) {
Box(
modifier = Modifier
.defaultMinSize(minHeight = 32.dp)
.padding(start = 8.dp, end = 8.dp)
.weight(0.75f)
.clip(RoundedCornerShape(12.dp))
.background(bgColor.lighterOrDarkerColor(0.10f))
.clickable {
onRequestRpeSelector(exerciseLogEntry)
},
contentAlignment = Alignment.Center
) {
Text(
exerciseLogEntry.rpe?.toReadableString() ?: "",
style = LocalTextStyle.current.copy(
textAlign = TextAlign.Center,
fontSize = 14.sp,
color = contentColor
)
)
}
ReboundSetTextField(
value = exerciseLogEntry.rpe?.toReadableString() ?: "",
onValueChange = {
onRpeChange(exerciseLogEntry, it.toFloatOrNull())
},
contentColor = contentColor,
bgColor = bgColor,
reboundKeyboardType = ReboundKeyboardType.RPE
)
// Box(
// modifier = Modifier
// .defaultMinSize(minHeight = 32.dp)
// .padding(start = 8.dp, end = 8.dp)
// .weight(0.75f)
// .clip(RoundedCornerShape(12.dp))
// .background(bgColor.lighterOrDarkerColor(0.10f))
// .clickable {
// onRequestRpeSelector(exerciseLogEntry)
// },
// contentAlignment = Alignment.Center
// ) {
// Text(
// exerciseLogEntry.rpe?.toReadableString() ?: "",
// style = LocalTextStyle.current.copy(
// textAlign = TextAlign.Center,
// fontSize = 14.sp,
// color = contentColor
// )
// )
// }
}

IconButton(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import com.ankitsuda.rebound.ui.keyboard.models.NumKey
import com.ankitsuda.rebound.ui.keyboard.models.NumberNumKey
import com.ankitsuda.rebound.ui.keyboard.picker.WarmUpListPickerComponent
import com.ankitsuda.rebound.ui.keyboard.platecalculator.PlateCalculatorComponent
import com.ankitsuda.rebound.ui.keyboard.rpe.RpePickerComponent
import com.ankitsuda.rebound.ui.theme.LocalThemeState

@OptIn(ExperimentalAnimationApi::class)
Expand All @@ -52,6 +53,7 @@ fun ReboundSetKeyboardComponent(
val currentMode = when (reboundKeyboardType) {
ReboundKeyboardType.WEIGHT -> mCurrentMode
ReboundKeyboardType.WARMUP_SET -> KeyboardModeType.WARMUP_PICKER
ReboundKeyboardType.RPE -> KeyboardModeType.RPE_PICKER
else -> KeyboardModeType.NUMBERS
}

Expand All @@ -71,6 +73,22 @@ fun ReboundSetKeyboardComponent(
)
}

fun setText(text: String) {
val currentText = inputConnection?.getText() ?: ""
val beforeCursorText =
inputConnection?.getTextBeforeCursor(currentText.length, 0) ?: ""
val afterCursorText =
inputConnection?.getTextAfterCursor(currentText.length, 0) ?: ""
inputConnection?.deleteSurroundingText(
beforeCursorText.length,
afterCursorText.length
)
inputConnection?.commitText(
text,
1
)
}

Box {
AnimatedContent(
targetState = currentMode,
Expand Down Expand Up @@ -116,24 +134,22 @@ fun ReboundSetKeyboardComponent(
}
KeyboardModeType.WARMUP_PICKER -> {
WarmUpListPickerComponent(
onSetText = {
val currentText = inputConnection?.getText() ?: ""
val beforeCursorText =
inputConnection?.getTextBeforeCursor(currentText.length, 0) ?: ""
val afterCursorText =
inputConnection?.getTextAfterCursor(currentText.length, 0) ?: ""
inputConnection?.deleteSurroundingText(
beforeCursorText.length,
afterCursorText.length
)
inputConnection?.commitText(
it,
1
)
},
onSetText = ::setText,
startingText = inputConnection?.getText()
)
}
KeyboardModeType.RPE_PICKER -> {
RpePickerComponent(
modifier = Modifier
.fillMaxWidth()
.height(
height = 250.dp,
),
onSetText = ::setText,
text = inputConnection?.getText(),
refreshKey = inputConnection
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ package com.ankitsuda.rebound.ui.keyboard.enums
enum class KeyboardModeType {
NUMBERS,
PLATE_CALCULATOR,
WARMUP_PICKER;
WARMUP_PICKER,
RPE_PICKER;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ enum class ReboundKeyboardType {
REPS,
DISTANCE,
TIME,
WARMUP_SET;
WARMUP_SET,
RPE;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2022 Ankit Suda.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/

package com.ankitsuda.rebound.ui.keyboard.rpe

import androidx.compose.foundation.layout.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.ankitsuda.base.util.toReadableString

@Composable
internal fun RpePickerComponent(
modifier: Modifier,
onSetText: (String) -> Unit,
text: String?,
refreshKey: Any?,
) {
var rpe: Float? by remember(text) {
mutableStateOf(text?.toFloatOrNull().takeIf { allRPEs.any { r -> r == it } })
}

Box(
modifier = modifier,
contentAlignment = Alignment.Center
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
SelectedRpeOverview(
modifier = Modifier.fillMaxWidth(),
rpe = rpe,
)
RpeSlider(
modifier = Modifier.fillMaxWidth(),
value = rpe,
refreshKey = refreshKey,
onValueChange = {
rpe = it
onSetText(rpe?.toReadableString()?:"")
}
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2022 Ankit Suda.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/

package com.ankitsuda.rebound.ui.keyboard.rpe

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Slider
import androidx.compose.material.SliderDefaults
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import com.ankitsuda.base.util.toLegacyInt
import com.ankitsuda.base.util.toReadableString
import com.ankitsuda.rebound.ui.theme.ReboundTheme
import kotlin.math.roundToInt

internal val allRPEs = listOf(null, 6f, 7f, 7.5f, 8f, 8.5f, 9f, 9.5f, 10f)

@Composable
internal fun RpeSlider(
modifier: Modifier,
value: Float?,
refreshKey: Any?,
onValueChange: (Float?) -> Unit,
) {
var mValue by remember(refreshKey) {
mutableStateOf(with(allRPEs.indexOf(value)) {
if (this == -1) 0f else this.toFloat()
})
}

val drawPadding = with(LocalDensity.current) { 10.dp.toPx() }
val textSize = with(LocalDensity.current) { 10.dp.toPx() }
val lineHeightDp = 10.dp
val lineHeightPx = with(LocalDensity.current) { lineHeightDp.toPx() }
val canvasHeight = 50.dp
val textPaint = android.graphics.Paint().apply {
color = ReboundTheme.colors.onBackground.toLegacyInt()
textAlign = android.graphics.Paint.Align.CENTER
this.textSize = textSize
}
Box(
modifier = modifier,
contentAlignment = Alignment.Center
) {
Canvas(
modifier = Modifier
.height(canvasHeight)
.fillMaxWidth()
.padding(
top = canvasHeight
.div(2)
.minus(lineHeightDp.div(2))
)
) {
val yStart = 0f
val distance = (size.width.minus(2 * drawPadding)).div(allRPEs.size.minus(1))
allRPEs.forEachIndexed { index, rpe ->
drawLine(
color = Color.DarkGray,
start = Offset(x = drawPadding + index.times(distance), y = yStart),
end = Offset(x = drawPadding + index.times(distance), y = lineHeightPx)
)
// if (index.rem(2) == 1) {
this.drawContext.canvas.nativeCanvas.drawText(
rpe?.toReadableString() ?: "?",
drawPadding + index.times(distance),
size.height,
textPaint
)
// }
}
}
Slider(
modifier = Modifier.fillMaxWidth(),
value = mValue,
valueRange = 0f..(allRPEs.size - 1).toFloat(),
steps = allRPEs.size - 2,
colors = SliderDefaults.colors(
activeTickColor = Color.Transparent,
inactiveTickColor = Color.Transparent
),
onValueChange = {
mValue = it
onValueChange(allRPEs.getOrNull(it.roundToInt()))
})
}
}
Loading

0 comments on commit 54dc5ae

Please sign in to comment.