mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 15:11:58 +01:00
settings: snap the preamp to its grid and drop a duplicate header
Review follow-ups. - Remove the second "Playback" section header the rows were added under; the section already had one, so the screen rendered it twice. - Snap the preamp to the 0.5 dB grid in the dialog. Material's slider snaps in pixel space and converts back, so the value it reports is near the configured grid but not on it: -1.0 dB arrives as -0.99999905, was displayed verbatim and was stored that way until the next drag. The step count is now derived from the range rather than hardcoded. - Format the decibel value with the resource locale so translated layouts get their own decimal separator. - The controls move to `ReplayGainControls.kt`, since the file now holds the grid as well as the labels, and the snap is covered by a test that reproduces the off-grid value without it.
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
package com.subtracks.ui.settings
|
||||
|
||||
import android.content.res.Resources
|
||||
import com.subtracks.R
|
||||
import com.subtracks.data.prefs.MAX_REPLAY_GAIN_PREAMP_DB
|
||||
import com.subtracks.data.prefs.MIN_REPLAY_GAIN_PREAMP_DB
|
||||
import com.subtracks.data.prefs.ReplayGainMode
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
internal const val REPLAY_GAIN_PREAMP_STEP_DB = 0.5f
|
||||
|
||||
internal val REPLAY_GAIN_PREAMP_STEPS =
|
||||
((MAX_REPLAY_GAIN_PREAMP_DB - MIN_REPLAY_GAIN_PREAMP_DB) / REPLAY_GAIN_PREAMP_STEP_DB).toInt() - 1
|
||||
|
||||
// Material's slider snaps in pixel space and converts back, so the value it reports is near, but not
|
||||
// on, the grid it was configured with (for example -0.99999905 for -1.0). Snap before showing or
|
||||
// storing it.
|
||||
internal fun snapReplayGainPreampDb(value: Float): Float = (value / REPLAY_GAIN_PREAMP_STEP_DB).roundToInt() * REPLAY_GAIN_PREAMP_STEP_DB
|
||||
|
||||
internal fun replayGainModeLabel(
|
||||
resources: Resources,
|
||||
mode: ReplayGainMode,
|
||||
): String =
|
||||
when (mode) {
|
||||
ReplayGainMode.Off -> resources.getString(R.string.settings_replay_gain_mode_off)
|
||||
ReplayGainMode.Track -> resources.getString(R.string.settings_replay_gain_mode_track)
|
||||
ReplayGainMode.Album -> resources.getString(R.string.settings_replay_gain_mode_album)
|
||||
}
|
||||
|
||||
internal fun replayGainPreampLabel(
|
||||
resources: Resources,
|
||||
decibels: Float,
|
||||
): String {
|
||||
val sign = if (decibels > 0f) "+" else ""
|
||||
val magnitude = String.format(resources.configuration.locales[0], "%.1f", decibels)
|
||||
return resources.getString(R.string.settings_replay_gain_preamp_value, "$sign$magnitude")
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.subtracks.ui.settings
|
||||
|
||||
import android.content.res.Resources
|
||||
import com.subtracks.R
|
||||
import com.subtracks.data.prefs.ReplayGainMode
|
||||
|
||||
internal fun replayGainModeLabel(
|
||||
resources: Resources,
|
||||
mode: ReplayGainMode,
|
||||
): String =
|
||||
when (mode) {
|
||||
ReplayGainMode.Off -> resources.getString(R.string.settings_replay_gain_mode_off)
|
||||
ReplayGainMode.Track -> resources.getString(R.string.settings_replay_gain_mode_track)
|
||||
ReplayGainMode.Album -> resources.getString(R.string.settings_replay_gain_mode_album)
|
||||
}
|
||||
|
||||
internal fun replayGainPreampLabel(
|
||||
resources: Resources,
|
||||
decibels: Float,
|
||||
): String {
|
||||
val sign = if (decibels > 0f) "+" else ""
|
||||
return resources.getString(R.string.settings_replay_gain_preamp_value, "$sign$decibels")
|
||||
}
|
||||
@@ -361,7 +361,6 @@ fun SettingsScreen(
|
||||
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
|
||||
)
|
||||
}
|
||||
item { SectionHeader(stringResource(R.string.settings_music_name)) }
|
||||
item {
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.settings_replay_gain_title)) },
|
||||
@@ -729,8 +728,6 @@ private fun SyncModeDialog(
|
||||
)
|
||||
}
|
||||
|
||||
private const val REPLAY_GAIN_PREAMP_STEPS = 59
|
||||
|
||||
@Composable
|
||||
private fun ReplayGainModeDialog(
|
||||
selected: ReplayGainMode,
|
||||
@@ -771,7 +768,7 @@ private fun ReplayGainPreampDialog(
|
||||
onDismiss: () -> Unit,
|
||||
) {
|
||||
val resources = LocalResources.current
|
||||
var draft by remember(selected) { mutableFloatStateOf(selected) }
|
||||
var draft by remember(selected) { mutableFloatStateOf(snapReplayGainPreampDb(selected)) }
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(stringResource(R.string.settings_replay_gain_preamp_title)) },
|
||||
@@ -784,7 +781,7 @@ private fun ReplayGainPreampDialog(
|
||||
)
|
||||
Slider(
|
||||
value = draft,
|
||||
onValueChange = { draft = it },
|
||||
onValueChange = { draft = snapReplayGainPreampDb(it) },
|
||||
valueRange = MIN_REPLAY_GAIN_PREAMP_DB..MAX_REPLAY_GAIN_PREAMP_DB,
|
||||
steps = REPLAY_GAIN_PREAMP_STEPS,
|
||||
)
|
||||
|
||||
+19
-1
@@ -3,13 +3,15 @@ package com.subtracks.ui.settings
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.subtracks.data.prefs.MAX_REPLAY_GAIN_PREAMP_DB
|
||||
import com.subtracks.data.prefs.MIN_REPLAY_GAIN_PREAMP_DB
|
||||
import com.subtracks.data.prefs.ReplayGainMode
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ReplayGainLabelsTest {
|
||||
class ReplayGainControlsTest {
|
||||
private val resources = ApplicationProvider.getApplicationContext<Context>().resources
|
||||
|
||||
@Test
|
||||
@@ -25,4 +27,20 @@ class ReplayGainLabelsTest {
|
||||
assertEquals("-2.5 dB", replayGainPreampLabel(resources, -2.5f))
|
||||
assertEquals("0.0 dB", replayGainPreampLabel(resources, 0f))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun theSliderHasOneStepPerHalfDecibel() {
|
||||
assertEquals(60, ((MAX_REPLAY_GAIN_PREAMP_DB - MIN_REPLAY_GAIN_PREAMP_DB) / REPLAY_GAIN_PREAMP_STEP_DB).toInt())
|
||||
assertEquals(59, REPLAY_GAIN_PREAMP_STEPS)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun thePreampSnapsBackOntoTheHalfDecibelGrid() {
|
||||
assertEquals(0f, snapReplayGainPreampDb(-0f), 0f)
|
||||
assertEquals(-1f, snapReplayGainPreampDb(-0.99999905f), 0f)
|
||||
assertEquals(-3f, snapReplayGainPreampDb(-3.000001f), 0f)
|
||||
assertEquals(14.5f, snapReplayGainPreampDb(14.6f), 0f)
|
||||
assertEquals(MAX_REPLAY_GAIN_PREAMP_DB, snapReplayGainPreampDb(14.9f), 0f)
|
||||
assertEquals(MIN_REPLAY_GAIN_PREAMP_DB, snapReplayGainPreampDb(-14.9f), 0f)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user