Skip to content

Commit f0273aa

Browse files
Made haptics really smooth
1 parent fa668c3 commit f0273aa

File tree

1 file changed

+61
-22
lines changed
  • app/src/main/java/com/jamesfrench/nothingcalculator

1 file changed

+61
-22
lines changed

app/src/main/java/com/jamesfrench/nothingcalculator/Buttons.kt

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.jamesfrench.nothingcalculator
22

3+
import android.os.Build
4+
import android.os.VibrationEffect
5+
import androidx.annotation.RequiresApi
36
import androidx.compose.animation.animateColorAsState
47
import androidx.compose.animation.core.EaseIn
58
import androidx.compose.animation.core.EaseOut
@@ -21,8 +24,11 @@ import androidx.compose.foundation.layout.wrapContentHeight
2124
import androidx.compose.foundation.shape.RoundedCornerShape
2225
import androidx.compose.material3.Text
2326
import androidx.compose.runtime.Composable
27+
import androidx.compose.runtime.LaunchedEffect
2428
import androidx.compose.runtime.getValue
29+
import androidx.compose.runtime.mutableStateOf
2530
import androidx.compose.runtime.remember
31+
import androidx.compose.runtime.setValue
2632
import androidx.compose.ui.Alignment
2733
import androidx.compose.ui.Modifier
2834
import androidx.compose.ui.draw.drawBehind
@@ -31,6 +37,7 @@ import androidx.compose.ui.geometry.Offset
3137
import androidx.compose.ui.geometry.Size
3238
import androidx.compose.ui.graphics.Color
3339
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
40+
import androidx.compose.ui.platform.LocalContext
3441
import androidx.compose.ui.platform.LocalHapticFeedback
3542
import androidx.compose.ui.res.stringResource
3643
import androidx.compose.ui.text.font.FontFamily
@@ -46,38 +53,39 @@ import com.jamesfrench.nothingcalculator.ui.theme.SqueezedDeepWhite
4653
import com.jamesfrench.nothingcalculator.ui.theme.SqueezedNothingRed
4754
import com.jamesfrench.nothingcalculator.ui.theme.ndot77
4855
import com.jamesfrench.nothingcalculator.ui.theme.notosans
56+
import android.os.Vibrator
4957

50-
data class KeysValue(val symbol: Any, val category: String, val background: Color, val font: FontFamily, val weight: Float, val value: Any = symbol)
58+
data class KeysValue(val symbol: Any, val category: String, val background: Color, val font: FontFamily, val weight: Float, val number_of_pulses: Int, val value: Any = symbol)
5159

5260
private val KeysValues = listOf(
5361
listOf(
54-
KeysValue("(", "number", NothingRed, ndot77, 1f, "("),
55-
KeysValue("%", "suffix",NothingRed, ndot77, 1f),
56-
KeysValue("÷", "operator",NothingRed, ndot77, 1f, "/"),
57-
KeysValue("×", "operator",NothingRed, ndot77, 1f, "*")
62+
KeysValue("(", "number", NothingRed, ndot77, 1f, 1, "("),
63+
KeysValue("%", "suffix",NothingRed, ndot77, 1f, 1),
64+
KeysValue("÷", "operator",NothingRed, ndot77, 1f, 1, "/"),
65+
KeysValue("×", "operator",NothingRed, ndot77, 1f, 1, "*")
5866
),
5967
listOf(
60-
KeysValue("7", "number",ContrastedGray, notosans, 1f),
61-
KeysValue("8", "number",ContrastedGray, notosans, 1f),
62-
KeysValue("9", "number",ContrastedGray, notosans, 1f),
63-
KeysValue("", "negative",NothingRed, ndot77, 1f, "-")
68+
KeysValue("7", "number",ContrastedGray, notosans, 1f, 1),
69+
KeysValue("8", "number",ContrastedGray, notosans, 1f, 1),
70+
KeysValue("9", "number",ContrastedGray, notosans, 1f, 1),
71+
KeysValue("", "negative",NothingRed, ndot77, 1f, 1, "-")
6472
),
6573
listOf(
66-
KeysValue("4", "number",ContrastedGray, notosans, 1f),
67-
KeysValue("5", "number",ContrastedGray, notosans, 1f),
68-
KeysValue("6", "number",ContrastedGray, notosans, 1f),
69-
KeysValue("+", "operator",NothingRed, ndot77, 1f)
74+
KeysValue("4", "number",ContrastedGray, notosans, 1f, 1),
75+
KeysValue("5", "number",ContrastedGray, notosans, 1f, 1),
76+
KeysValue("6", "number",ContrastedGray, notosans, 1f, 1),
77+
KeysValue("+", "operator",NothingRed, ndot77, 1f, 1)
7078
),
7179
listOf(
72-
KeysValue("1", "number",ContrastedGray, notosans, 1f),
73-
KeysValue("2", "number",ContrastedGray, notosans, 1f),
74-
KeysValue("3", "number",ContrastedGray, notosans, 1f),
75-
KeysValue(R.string.decimal, "number",NothingRed, ndot77, 1f, ".")
80+
KeysValue("1", "number",ContrastedGray, notosans, 1f, 1),
81+
KeysValue("2", "number",ContrastedGray, notosans, 1f, 1),
82+
KeysValue("3", "number",ContrastedGray, notosans, 1f, 1),
83+
KeysValue(R.string.decimal, "number",NothingRed, ndot77, 1f, 1, ".")
7684
),
7785
listOf(
78-
KeysValue("0", "number",ContrastedGray, notosans, 2f),
79-
KeysValue("<", "del",DeepWhite, ndot77, 1f),
80-
KeysValue("=", "equal",NothingRed, ndot77, 1f)
86+
KeysValue("0", "number",ContrastedGray, notosans, 2f, 1),
87+
KeysValue("<", "del",DeepWhite, ndot77, 1f, 1),
88+
KeysValue("=", "equal",NothingRed, ndot77, 1f, 3)
8189
)
8290
)
8391

@@ -92,8 +100,9 @@ fun squeezedColor(color: Color): Color {
92100
return squeezedColor
93101
}
94102

103+
@RequiresApi(Build.VERSION_CODES.O)
95104
@Composable
96-
fun Key(viewModel: SharedViewModel, text: String, value: String, category: String, background: Color, foreground: Color, font: FontFamily, modifier: Modifier = Modifier) {
105+
fun Key(viewModel: SharedViewModel, text: String, value: String, category: String, background: Color, foreground: Color, font: FontFamily, number_of_pulses: Int, modifier: Modifier = Modifier) {
97106
val haptic = LocalHapticFeedback.current
98107
val interactionSource = remember { MutableInteractionSource() }
99108
val isPressed = interactionSource.collectIsPressedAsState().value
@@ -116,6 +125,31 @@ fun Key(viewModel: SharedViewModel, text: String, value: String, category: Strin
116125
tween(150, easing = EaseIn)
117126
)
118127

128+
var hapticEngine by remember { mutableStateOf<VibrationEffect?>(null) }
129+
val context = LocalContext.current
130+
131+
// https://medium.com/@jpmtech/haptics-in-jetpack-compose-06ac8adaf985
132+
// May change the code when i'm a bit more advanced in programming apps
133+
LaunchedEffect(key1 = Unit) {
134+
val numberOfPulses = number_of_pulses // Number of increasing haptic pulses
135+
val pulseDuration = 20L // Duration of each pulse in milliseconds
136+
val spaceBetweenPulses = 20L // Duration of space between pulses in milliseconds
137+
val maxAmplitude = 255 // Maximum amplitude for the last pulse
138+
139+
val timings = LongArray(numberOfPulses * 2) // Double the size for on/off
140+
val amplitudes = IntArray(numberOfPulses * 2)
141+
142+
for (i in 0 until numberOfPulses) {
143+
val amplitude = (maxAmplitude * (i + 1) / numberOfPulses) // Calculate increasing amplitude
144+
timings[i * 2] = spaceBetweenPulses // Space before the pulse
145+
timings[i * 2 + 1] = pulseDuration // Duration of the pulse
146+
amplitudes[i * 2] = 0 // Amplitude of the space
147+
amplitudes[i * 2 + 1] = amplitude // Amplitude of the pulse
148+
}
149+
150+
hapticEngine = VibrationEffect.createWaveform(timings, amplitudes, -1)
151+
}
152+
119153
Box(
120154
modifier = modifier
121155
.drawBehind {
@@ -136,7 +170,11 @@ fun Key(viewModel: SharedViewModel, text: String, value: String, category: Strin
136170
onClickLabel = null,
137171
role = null,
138172
onClick = {
139-
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
173+
//haptic.performHapticFeedback(HapticFeedbackType.LongPress)
174+
hapticEngine?.let {
175+
val vibrator = context.getSystemService(Vibrator::class.java)
176+
vibrator.vibrate(it)
177+
}
140178
viewModel.keyPressed(value)
141179
}
142180
),
@@ -194,6 +232,7 @@ fun KeysRows(viewModel: SharedViewModel, number: Int) {
194232
key.background,
195233
if (key.background == DeepWhite) DeepBlack else DeepWhite,
196234
key.font,
235+
key.number_of_pulses,
197236
modifier = Modifier
198237
.weight(key.weight)
199238
.aspectRatio(1f * key.weight)

0 commit comments

Comments
 (0)