From 30f8e34fd1f22b8b44e3b68752945a6504b46a03 Mon Sep 17 00:00:00 2001 From: AbdallahMehiz Date: Sun, 8 Sep 2024 11:54:43 +0100 Subject: [PATCH] feat: display volume as percentage setting --- .../mpvkt/preferences/PlayerPreferences.kt | 1 + .../mehiz/mpvkt/ui/player/PlayerActivity.kt | 6 +- .../mehiz/mpvkt/ui/player/PlayerViewModel.kt | 1 + .../ui/player/controls/GestureHandler.kt | 4 +- .../ui/player/controls/PlayerControls.kt | 4 +- .../controls/components/VerticalSliders.kt | 61 +++++++++++++++---- .../ui/preferences/PlayerPreferencesScreen.kt | 6 ++ app/src/main/res/values/strings.xml | 11 ++++ 8 files changed, 76 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/live/mehiz/mpvkt/preferences/PlayerPreferences.kt b/app/src/main/java/live/mehiz/mpvkt/preferences/PlayerPreferences.kt index cfbb949..59e9c7e 100644 --- a/app/src/main/java/live/mehiz/mpvkt/preferences/PlayerPreferences.kt +++ b/app/src/main/java/live/mehiz/mpvkt/preferences/PlayerPreferences.kt @@ -32,6 +32,7 @@ class PlayerPreferences( "default_speed_presets", setOf("0.25", "0.5", "0.75", "1.0", "1.25", "1.5", "1.75", "2.0", "2.5", "3.0", "3.5", "4.0") ) + val displayVolumeAsPercentage = preferenceStore.getBoolean("display_volume_as_percentage", true) val savePositionOnQuit = preferenceStore.getBoolean("save_position", true) val automaticallyEnterPip = preferenceStore.getBoolean("automatic_pip") diff --git a/app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerActivity.kt b/app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerActivity.kt index 31a910e..24e09f4 100644 --- a/app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerActivity.kt +++ b/app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerActivity.kt @@ -291,10 +291,10 @@ class PlayerActivity : AppCompatActivity() { if (it < viewModel.maxVolume) viewModel.changeMPVVolumeTo(100) } } - viewModel.changeBrightnessTo( + viewModel.currentBrightness.update { Settings.System.getFloat(contentResolver, Settings.System.SCREEN_BRIGHTNESS) - .normalize(0f, 255f, 0f, 1f), - ) + .normalize(0f, 255f, 0f, 1f) + } } private fun setupIntents(intent: Intent) { diff --git a/app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerViewModel.kt b/app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerViewModel.kt index 3d933bd..c966920 100644 --- a/app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerViewModel.kt +++ b/app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerViewModel.kt @@ -332,6 +332,7 @@ class PlayerViewModel( fun changeBrightnessTo( brightness: Float, ) { + isBrightnessSliderShown.update { true } currentBrightness.update { brightness.coerceIn(0f, 1f) } activity.window.attributes = activity.window.attributes.apply { screenBrightness = brightness.coerceIn(0f, 1f) diff --git a/app/src/main/java/live/mehiz/mpvkt/ui/player/controls/GestureHandler.kt b/app/src/main/java/live/mehiz/mpvkt/ui/player/controls/GestureHandler.kt index c5560db..a4cabe9 100644 --- a/app/src/main/java/live/mehiz/mpvkt/ui/player/controls/GestureHandler.kt +++ b/app/src/main/java/live/mehiz/mpvkt/ui/player/controls/GestureHandler.kt @@ -282,7 +282,9 @@ fun GestureHandler(modifier: Modifier = Modifier) { } val changeBrightness: () -> Unit = { if (startingY == 0f) startingY = change.position.y - calculateNewValue(originalBrightness, startingY, change.position.y, brightnessGestureSens) + viewModel.changeBrightnessTo( + calculateNewValue(originalBrightness, startingY, change.position.y, brightnessGestureSens) + ) } when { volumeGesture && brightnessGesture -> { diff --git a/app/src/main/java/live/mehiz/mpvkt/ui/player/controls/PlayerControls.kt b/app/src/main/java/live/mehiz/mpvkt/ui/player/controls/PlayerControls.kt index 830fa12..7836a67 100644 --- a/app/src/main/java/live/mehiz/mpvkt/ui/player/controls/PlayerControls.kt +++ b/app/src/main/java/live/mehiz/mpvkt/ui/player/controls/PlayerControls.kt @@ -170,11 +170,13 @@ fun PlayerControls( }, ) { val boostCap by audioPreferences.volumeBoostCap.collectAsState() + val displayVolumeAsPercentage by playerPreferences.displayVolumeAsPercentage.collectAsState() VolumeSlider( volume, mpvVolume = mpvVolume, range = 0..viewModel.maxVolume, - boostRange = if (boostCap > 0) 0..audioPreferences.volumeBoostCap.get() else null + boostRange = if (boostCap > 0) 0..audioPreferences.volumeBoostCap.get() else null, + displayAsPercentage = displayVolumeAsPercentage ) } diff --git a/app/src/main/java/live/mehiz/mpvkt/ui/player/controls/components/VerticalSliders.kt b/app/src/main/java/live/mehiz/mpvkt/ui/player/controls/components/VerticalSliders.kt index 76c4cc5..642ecfb 100644 --- a/app/src/main/java/live/mehiz/mpvkt/ui/player/controls/components/VerticalSliders.kt +++ b/app/src/main/java/live/mehiz/mpvkt/ui/player/controls/components/VerticalSliders.kt @@ -26,9 +26,12 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import live.mehiz.mpvkt.R import live.mehiz.mpvkt.ui.theme.spacing import kotlin.math.abs +import kotlin.math.roundToInt fun percentage(value: Float, range: ClosedFloatingPointRange): Float { return ((value - range.start) / (range.endInclusive - range.start)).coerceIn(0f, 1f) @@ -154,7 +157,9 @@ fun VolumeSlider( range: ClosedRange, boostRange: ClosedRange?, modifier: Modifier = Modifier, + displayAsPercentage: Boolean = false, ) { + val percentage = (percentage(volume, range) * 100).roundToInt() Column( modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally, @@ -162,29 +167,59 @@ fun VolumeSlider( ) { val boostVolume = mpvVolume - 100 Text( - when (mpvVolume - 100) { - 0 -> "$volume" - in 0..1000 -> "$volume + $boostVolume" - in -100..-1 -> "$volume - ${abs(boostVolume)}" - else -> "$volume ($mpvVolume)" - }, + getVolumeSliderText(volume, mpvVolume, boostVolume, percentage, displayAsPercentage), style = MaterialTheme.typography.bodySmall, ) VerticalSlider( - volume, - range, + if (displayAsPercentage) percentage else volume, + if (displayAsPercentage) 0..100 else range, overflowValue = boostVolume, overflowRange = boostRange, ) Icon( - when (percentage(volume, range)) { - 0f -> Icons.AutoMirrored.Default.VolumeOff - in 0f..0.3f -> Icons.AutoMirrored.Default.VolumeMute - in 0.3f..0.6f -> Icons.AutoMirrored.Default.VolumeDown - in 0.6f..1f -> Icons.AutoMirrored.Default.VolumeUp + when (percentage) { + 0 -> Icons.AutoMirrored.Default.VolumeOff + in 0..30 -> Icons.AutoMirrored.Default.VolumeMute + in 30..60 -> Icons.AutoMirrored.Default.VolumeDown + in 60..100 -> Icons.AutoMirrored.Default.VolumeUp else -> Icons.AutoMirrored.Default.VolumeOff }, null, ) } } + +val getVolumeSliderText: @Composable (Int, Int, Int, Int, Boolean) -> String = + { volume, mpvVolume, boostVolume, percentage, displayAsPercentage -> + when (mpvVolume - 100) { + 0 -> if (displayAsPercentage) { + stringResource(R.string.value_percentage_int, percentage) + } else { + "$volume" + } + + in 0..1000 -> { + if (displayAsPercentage) { + stringResource(R.string.volume_slider_percentage_positive_boost, percentage, boostVolume) + } else { + stringResource(R.string.volume_slider_steps_positive_boost, volume, boostVolume) + } + } + + in -100..-1 -> { + if (displayAsPercentage) { + stringResource(R.string.volume_slider_percentage_negative_boost, percentage, abs(boostVolume)) + } else { + stringResource(R.string.volume_slider_steps_negative_boost, volume, abs(boostVolume)) + } + } + + else -> { + if (displayAsPercentage) { + stringResource(R.string.volume_slider_percentage_other, percentage, boostVolume) + } else { + stringResource(R.string.volume_slider_steps_other, volume, boostVolume) + } + } + } + } diff --git a/app/src/main/java/live/mehiz/mpvkt/ui/preferences/PlayerPreferencesScreen.kt b/app/src/main/java/live/mehiz/mpvkt/ui/preferences/PlayerPreferencesScreen.kt index bb05783..a4a70c1 100644 --- a/app/src/main/java/live/mehiz/mpvkt/ui/preferences/PlayerPreferencesScreen.kt +++ b/app/src/main/java/live/mehiz/mpvkt/ui/preferences/PlayerPreferencesScreen.kt @@ -168,6 +168,12 @@ object PlayerPreferencesScreen : Screen() { onValueChange = preferences.allowGesturesInPanels::set, title = { Text(text = stringResource(id = R.string.pref_player_controls_allow_gestures_in_panels)) }, ) + val displayVolumeAsPercentage by preferences.displayVolumeAsPercentage.collectAsState() + SwitchPreference( + value = displayVolumeAsPercentage, + onValueChange = preferences.displayVolumeAsPercentage::set, + title = { Text(stringResource(R.string.pref_player_display_volume_as_percentage)) }, + ) val showChaptersButton by preferences.showChaptersButton.collectAsState() SwitchPreference( value = showChaptersButton, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a6efbb4..4b62059 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -49,6 +49,7 @@ Seek to exact positions instead of keyframes (slow) Automatically switch to PiP Close after the end of playback + Display volume as percentage Gestures Horizontal seek gestures @@ -190,6 +191,16 @@ Sleep timer ended + %d%% + %d + %d%% - %d + %d%% (%d) + %d + %d + %d - %d + %d (%d) + + %d%% + %.2f\%% + https://github.com/abdallahmehiz/mpvKt