Migrate WidgetBrightDisplayConfigureActivity to compose

This commit is contained in:
Ensar Sarajčić 2023-09-28 16:57:00 +02:00
parent 68f4e32ce2
commit 0ff554a835
3 changed files with 187 additions and 58 deletions

View File

@ -1,50 +1,66 @@
package com.simplemobiletools.flashlight.activities package com.simplemobiletools.flashlight.activities
import android.app.Activity import android.app.Activity
import android.app.Application
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.content.Intent import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.widget.SeekBar import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.runtime.getValue
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.simplemobiletools.commons.compose.extensions.enableEdgeToEdgeSimple
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.dialogs.ColorPickerDialog import com.simplemobiletools.commons.dialogs.ColorPickerDialog
import com.simplemobiletools.commons.dialogs.FeatureLockedDialog import com.simplemobiletools.commons.dialogs.FeatureLockedDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.isOrWasThankYouInstalled
import com.simplemobiletools.commons.helpers.IS_CUSTOMIZING_COLORS import com.simplemobiletools.commons.helpers.IS_CUSTOMIZING_COLORS
import com.simplemobiletools.flashlight.R import com.simplemobiletools.flashlight.R
import com.simplemobiletools.flashlight.databinding.WidgetBrightDisplayConfigBinding
import com.simplemobiletools.flashlight.extensions.config import com.simplemobiletools.flashlight.extensions.config
import com.simplemobiletools.flashlight.helpers.MyWidgetBrightDisplayProvider import com.simplemobiletools.flashlight.helpers.MyWidgetBrightDisplayProvider
import com.simplemobiletools.flashlight.screens.WidgetBrightDisplayConfigureScreen
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
class WidgetBrightDisplayConfigureActivity : SimpleActivity() { class WidgetBrightDisplayConfigureActivity : SimpleActivity() {
private val binding by viewBinding(WidgetBrightDisplayConfigBinding::inflate) private val viewModel by viewModels<WidgetBrightDisplayConfigureViewModel>()
private var mWidgetAlpha = 0f
private var mWidgetId = 0
private var mWidgetColor = 0
private var mWidgetColorWithoutTransparency = 0
private var mFeatureLockedDialog: FeatureLockedDialog? = null private var mFeatureLockedDialog: FeatureLockedDialog? = null
public override fun onCreate(savedInstanceState: Bundle?) { public override fun onCreate(savedInstanceState: Bundle?) {
useDynamicTheme = false useDynamicTheme = false
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setResult(Activity.RESULT_CANCELED) setResult(Activity.RESULT_CANCELED)
setContentView(binding.root)
initVariables()
val isCustomizingColors = intent.extras?.getBoolean(IS_CUSTOMIZING_COLORS) ?: false val isCustomizingColors = intent.extras?.getBoolean(IS_CUSTOMIZING_COLORS) ?: false
mWidgetId = intent.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID) ?: AppWidgetManager.INVALID_APPWIDGET_ID viewModel.setWidgetId(intent.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID) ?: AppWidgetManager.INVALID_APPWIDGET_ID)
if (mWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID && !isCustomizingColors) { if (viewModel.widgetId.value == AppWidgetManager.INVALID_APPWIDGET_ID && !isCustomizingColors) {
finish() finish()
} }
binding.apply { enableEdgeToEdgeSimple()
configSave.setOnClickListener { saveConfig() } setContent {
configWidgetColor.setOnClickListener { pickBackgroundColor() } AppThemeSurface {
val widgetColor by viewModel.widgetColor.collectAsStateWithLifecycle()
val widgetAlpha by viewModel.widgetAlpha.collectAsStateWithLifecycle()
val primaryColor = getProperPrimaryColor() WidgetBrightDisplayConfigureScreen(
configWidgetSeekbar.setColors(getProperTextColor(), primaryColor, primaryColor) widgetColor = widgetColor,
widgetAlpha = widgetAlpha,
onSliderChanged = {
viewModel.changeAlpha(it)
},
onColorPressed = {
pickBackgroundColor()
},
onSavePressed = {
saveConfig()
}
)
}
} }
if (!isCustomizingColors && !isOrWasThankYouInstalled()) { if (!isCustomizingColors && !isOrWasThankYouInstalled()) {
@ -54,11 +70,6 @@ class WidgetBrightDisplayConfigureActivity : SimpleActivity() {
} }
} }
} }
binding.configSave.apply {
backgroundTintList = ColorStateList.valueOf(getProperPrimaryColor())
setTextColor(getProperPrimaryColor().getContrastColor())
}
} }
override fun onResume() { override fun onResume() {
@ -70,65 +81,65 @@ class WidgetBrightDisplayConfigureActivity : SimpleActivity() {
} }
} }
private fun initVariables() {
mWidgetColor = config.widgetBgColor
if (mWidgetColor == resources.getColor(R.color.default_widget_bg_color) && config.isUsingSystemTheme) {
mWidgetColor = resources.getColor(R.color.you_primary_color, theme)
}
mWidgetAlpha = Color.alpha(mWidgetColor) / 255.toFloat()
mWidgetColorWithoutTransparency = Color.rgb(Color.red(mWidgetColor), Color.green(mWidgetColor), Color.blue(mWidgetColor))
binding.configWidgetSeekbar.apply {
setOnSeekBarChangeListener(seekbarChangeListener)
progress = (mWidgetAlpha * 100).toInt()
}
updateColors()
}
private fun saveConfig() { private fun saveConfig() {
config.widgetBgColor = mWidgetColor config.widgetBgColor = viewModel.widgetColor.value
requestWidgetUpdate() requestWidgetUpdate()
Intent().apply { Intent().apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId) putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, viewModel.widgetId.value)
setResult(Activity.RESULT_OK, this) setResult(Activity.RESULT_OK, this)
} }
finish() finish()
} }
private fun pickBackgroundColor() { private fun pickBackgroundColor() {
ColorPickerDialog(this, mWidgetColorWithoutTransparency) { wasPositivePressed, color -> ColorPickerDialog(this, viewModel.widgetColor.value) { wasPositivePressed, color ->
if (wasPositivePressed) { if (wasPositivePressed) {
mWidgetColorWithoutTransparency = color viewModel.updateColor(color)
updateColors()
} }
} }
} }
private fun requestWidgetUpdate() { private fun requestWidgetUpdate() {
Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidgetBrightDisplayProvider::class.java).apply { Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidgetBrightDisplayProvider::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(mWidgetId)) putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(viewModel.widgetId.value))
sendBroadcast(this) sendBroadcast(this)
} }
} }
private fun updateColors() { internal class WidgetBrightDisplayConfigureViewModel(
mWidgetColor = mWidgetColorWithoutTransparency.adjustAlpha(mWidgetAlpha) application: Application
binding.apply { ) : AndroidViewModel(application) {
configWidgetColor.setFillWithStroke(mWidgetColor, mWidgetColor)
configImage.background.mutate().applyColorFilter(mWidgetColor)
}
}
private val seekbarChangeListener = object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { private val _widgetAlpha = MutableStateFlow(0f)
mWidgetAlpha = progress.toFloat() / 100.toFloat() val widgetAlpha = _widgetAlpha.asStateFlow()
updateColors()
private val _widgetId = MutableStateFlow(0)
val widgetId = _widgetId.asStateFlow()
private val _widgetColor = MutableStateFlow(0)
val widgetColor = _widgetColor.asStateFlow()
fun changeAlpha(newAlpha: Float) {
_widgetAlpha.value = newAlpha
} }
override fun onStartTrackingTouch(seekBar: SeekBar) {} fun updateColor(newColor: Int) {
_widgetColor.value = newColor
}
override fun onStopTrackingTouch(seekBar: SeekBar) {} fun setWidgetId(widgetId: Int) {
_widgetId.value = widgetId
}
init {
_widgetColor.value = application.config.widgetBgColor
if (_widgetColor.value == application.resources.getColor(R.color.default_widget_bg_color) && application.config.isUsingSystemTheme) {
_widgetColor.value = application.resources.getColor(R.color.you_primary_color, application.theme)
}
_widgetAlpha.value = Color.alpha(_widgetColor.value) / 255f
}
} }
} }

View File

@ -0,0 +1,115 @@
package com.simplemobiletools.flashlight.screens
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.painter.BrushPainter
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.constraintlayout.compose.ConstraintLayout
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.extensions.adjustAlpha
import com.simplemobiletools.flashlight.R
@Composable
internal fun WidgetBrightDisplayConfigureScreen(
widgetColor: Int,
widgetAlpha: Float,
onSliderChanged: (Float) -> Unit,
onColorPressed: () -> Unit,
onSavePressed: () -> Unit
) {
ConstraintLayout(
modifier = Modifier.fillMaxSize()
) {
val (brightDisplay, bottomControls, saveButton) = createRefs()
Box(
modifier = Modifier
.padding(dimensionResource(id = R.dimen.activity_margin))
.padding(bottom = dimensionResource(id = R.dimen.activity_margin))
.constrainAs(brightDisplay) {
top.linkTo(parent.top)
end.linkTo(parent.end)
start.linkTo(parent.start)
bottom.linkTo(bottomControls.top)
}
) {
Icon(
modifier = Modifier
.align(Alignment.Center)
.size(dimensionResource(id = R.dimen.main_button_size)),
painter = painterResource(id = R.drawable.ic_bright_display_vector),
contentDescription = stringResource(id = R.string.bright_display),
tint = Color(widgetColor.adjustAlpha(widgetAlpha))
)
}
Row(
modifier = Modifier.constrainAs(bottomControls) {
bottom.linkTo(saveButton.top)
start.linkTo(parent.start)
end.linkTo(parent.end)
}
) {
Icon(
modifier = Modifier
.size(dimensionResource(id = R.dimen.widget_colorpicker_size))
.padding(dimensionResource(id = R.dimen.tiny_margin))
.clip(CircleShape)
.clickable { onColorPressed() },
painter = BrushPainter(SolidColor(Color(widgetColor))),
contentDescription = stringResource(id = R.string.bright_display),
tint = Color(widgetColor)
)
Slider(
value = widgetAlpha,
onValueChange = onSliderChanged,
modifier = Modifier
.padding(start = dimensionResource(id = R.dimen.medium_margin))
.background(
color = colorResource(id = R.color.md_grey_white),
shape = MaterialTheme.shapes.extraLarge
)
.padding(horizontal = dimensionResource(id = R.dimen.activity_margin))
)
}
Button(
modifier = Modifier.constrainAs(saveButton) {
end.linkTo(parent.end)
bottom.linkTo(parent.bottom)
},
onClick = onSavePressed
) {
Text(text = stringResource(id = R.string.ok))
}
}
}
@Composable
@MyDevices
private fun WidgetBrightDisplayConfigureScreenPreview() {
AppThemeSurface {
WidgetBrightDisplayConfigureScreen(
widgetColor = MaterialTheme.colorScheme.primary.toArgb(),
widgetAlpha = 1f,
onSliderChanged = {},
onColorPressed = {},
onSavePressed = {}
)
}
}

View File

@ -15,6 +15,7 @@ composeActivity = "1.8.0-rc01"
compose = "1.6.0-alpha06" compose = "1.6.0-alpha06"
composeCompiler = "1.5.3" composeCompiler = "1.5.3"
composeMaterial3 = "1.2.0-alpha08" composeMaterial3 = "1.2.0-alpha08"
composeConstraintLayout = "1.0.1"
#Gradle #Gradle
gradlePlugins-agp = "8.1.1" gradlePlugins-agp = "8.1.1"
#build #build
@ -44,6 +45,7 @@ simple-tools-commons = { module = "com.github.SimpleMobileTools:Simple-Commons",
#Compose #Compose
compose-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "composeCompiler" } compose-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "composeCompiler" }
compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" } compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" }
compose-constraintlayout = { module = "androidx.constraintlayout:constraintlayout-compose", version.ref = "composeConstraintLayout" }
compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "composeMaterial3" } compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "composeMaterial3" }
compose-material2 = { module = "androidx.compose.material:material", version.ref = "compose" } compose-material2 = { module = "androidx.compose.material:material", version.ref = "compose" }
compose-material-icons = { module = "androidx.compose.material:material-icons-extended", version.ref = "compose" } compose-material-icons = { module = "androidx.compose.material:material-icons-extended", version.ref = "compose" }
@ -61,6 +63,7 @@ compose = [
"compose-foundation", "compose-foundation",
"compose-material-icons", "compose-material-icons",
"compose-material3", "compose-material3",
"compose-constraintlayout",
"compose-runtime", "compose-runtime",
"compose-ui", "compose-ui",
"compose-uiTooling-preview", "compose-uiTooling-preview",