diff --git a/app/src/main/java/com/ankitsuda/rebound/ui/main/MainScreen.kt b/app/src/main/java/com/ankitsuda/rebound/ui/main/MainScreen.kt index e109fc17..da9def7f 100644 --- a/app/src/main/java/com/ankitsuda/rebound/ui/main/MainScreen.kt +++ b/app/src/main/java/com/ankitsuda/rebound/ui/main/MainScreen.kt @@ -23,6 +23,7 @@ import androidx.compose.material.icons.outlined.* import androidx.compose.runtime.* import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector @@ -31,6 +32,8 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.NavGraph.Companion.findStartDestination @@ -88,7 +91,10 @@ fun MainScreen( ) } -@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterialNavigationApi::class) +@OptIn( + ExperimentalMaterialApi::class, ExperimentalMaterialNavigationApi::class, + ExperimentalComposeUiApi::class +) @Composable private fun MainLayout( navController: NavHostController, @@ -233,12 +239,22 @@ private fun MainLayout( } if (dialogVisible) { - AlertDialog(onDismissRequest = { - dialogVisible = false - }, - buttons = { - dialogContent() - }) + Dialog( + properties = DialogProperties(usePlatformDefaultWidth = false), + onDismissRequest = { + dialogVisible = false + }, + content = { + Surface( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 32.dp), + color = ReboundTheme.colors.background, + shape = ReboundTheme.shapes.large, + content = dialogContent + ) + } + ) } } } diff --git a/buildSrc/src/main/java/com/ankitsuda/rebound/buildSrc/Deps.kt b/buildSrc/src/main/java/com/ankitsuda/rebound/buildSrc/Deps.kt index 9dcfa35c..046aa30c 100644 --- a/buildSrc/src/main/java/com/ankitsuda/rebound/buildSrc/Deps.kt +++ b/buildSrc/src/main/java/com/ankitsuda/rebound/buildSrc/Deps.kt @@ -64,7 +64,8 @@ object Deps { const val materialDesignIcons = "androidx.compose.material:material-icons-core:$version" const val materialDesignIconsExtended = "androidx.compose.material:material-icons-extended:$version" - const val constraintLayout = "androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha04" + const val constraintLayout = + "androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha04" const val liveData = "androidx.compose.runtime:runtime-livedata:$version" const val activity = "androidx.activity:activity-compose:$activityVersion" const val viewModels = "androidx.lifecycle:lifecycle-viewmodel-compose:2.4.0" @@ -132,6 +133,15 @@ object Deps { const val common = "androidx.paging:paging-common-ktx:$version" const val runtime = "androidx.paging:paging-runtime-ktx:$version" } + + object ColorPicker { + private const val version = "0.5.1" + const val composeColorPicker = + "com.godaddy.android.colorpicker:compose-color-picker:$version" + const val composeColorPickerAndroid = + "com.godaddy.android.colorpicker:compose-color-picker-android:$version" + + } } object Utils { diff --git a/modules/common-ui-components-settings/src/main/java/com/ankitsuda/rebound/ui/components/settings/color_pickers/ColorPickerDialog1.kt b/modules/common-ui-components-settings/src/main/java/com/ankitsuda/rebound/ui/components/settings/color_pickers/ColorPickerDialog1.kt index 586816ad..2aec8f8d 100644 --- a/modules/common-ui-components-settings/src/main/java/com/ankitsuda/rebound/ui/components/settings/color_pickers/ColorPickerDialog1.kt +++ b/modules/common-ui-components-settings/src/main/java/com/ankitsuda/rebound/ui/components/settings/color_pickers/ColorPickerDialog1.kt @@ -14,6 +14,8 @@ package com.ankitsuda.rebound.ui.components.settings.color_pickers +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.layout.* import androidx.compose.material.Text import androidx.compose.material.TextButton @@ -27,8 +29,10 @@ import com.ankitsuda.common.compose.LocalDialog import com.ankitsuda.rebound.ui.components.color_picker.ColorPicker1 import com.ankitsuda.rebound.ui.components.color_picker.ColorPickerPresets import com.ankitsuda.common.compose.R +import com.ankitsuda.rebound.ui.components.color_picker.ColorPicker2 +@OptIn(ExperimentalAnimationApi::class) @Composable fun ColorPickerDialog1( defaultColor: Color = Color.Red, @@ -43,48 +47,52 @@ fun ColorPickerDialog1( mutableStateOf(defaultColor) } - val screenHeight = (LocalConfiguration.current.screenHeightDp / 1.0).dp +// val screenHeight = (LocalConfiguration.current.screenHeightDp / 1.0).dp Column( modifier = Modifier .fillMaxWidth() - .height(screenHeight) +// .height(screenHeight) ) { - if (isPresetLayout) { - ColorPickerPresets( - modifier = Modifier - .fillMaxWidth() - .height(300.dp), - onColorPicked = { - selectedColor = it - }, - ) + AnimatedContent(targetState = isPresetLayout) { + if (it) { + ColorPickerPresets( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), +// .height(300.dp), + onColorPicked = { newColor -> + selectedColor = newColor + }, + ) - } else { - ColorPicker1( - modifier = Modifier - .fillMaxWidth() - .height(600.dp), - colorSelected = { - selectedColor = it - }, - defaultColor = defaultColor - ) + } else { + ColorPicker2( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + colorSelected = { newColor -> + selectedColor = newColor + }, + defaultColor = defaultColor + ) + } } - - Spacer(Modifier.height(16.dp)) - Row( horizontalArrangement = Arrangement.SpaceBetween, - modifier = Modifier.fillMaxWidth() + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 8.dp, start = 16.dp, end = 16.dp) ) { TextButton(onClick = { isPresetLayout = !isPresetLayout }) { Text( - text = if (isPresetLayout) stringResource(id = R.string.custom) else stringResource(id = R.string.presets) + text = if (isPresetLayout) stringResource(id = R.string.custom) else stringResource( + id = R.string.presets + ) ) } TextButton(onClick = with(LocalDialog.current) { diff --git a/modules/common-ui-components/build.gradle b/modules/common-ui-components/build.gradle index 8f478460..2096f87b 100644 --- a/modules/common-ui-components/build.gradle +++ b/modules/common-ui-components/build.gradle @@ -55,7 +55,11 @@ dependencies { api project(":modules:common-ui-icons") api project(":modules:navigation") api project(":modules:domain") + api Deps.Android.Compose.collapsingToolbar + api Deps.Android.ColorPicker.composeColorPicker + api Deps.Android.ColorPicker.composeColorPickerAndroid + kapt Deps.Dagger.hiltCompiler coreLibraryDesugaring Deps.Android.desugaring diff --git a/modules/common-ui-components/src/main/java/com/ankitsuda/rebound/ui/components/color_picker/ColorHexInfo.kt b/modules/common-ui-components/src/main/java/com/ankitsuda/rebound/ui/components/color_picker/ColorHexInfo.kt new file mode 100644 index 00000000..3e7857e9 --- /dev/null +++ b/modules/common-ui-components/src/main/java/com/ankitsuda/rebound/ui/components/color_picker/ColorHexInfo.kt @@ -0,0 +1,46 @@ +/* + * 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.components.color_picker + +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import com.ankitsuda.base.util.toHexString +import com.ankitsuda.rebound.ui.components.AppTextField +import com.ankitsuda.rebound.ui.components.R + +@Composable +fun ColorHexInfo( + modifier: Modifier = Modifier, + selectedColor: Color, + onHexEdited: (Color) -> Unit +) { + val mSelectedColor by remember(selectedColor) { + mutableStateOf(selectedColor) + } + var text by remember(selectedColor) { + mutableStateOf("#" + mSelectedColor.toHexString().uppercase()/*.drop(2)*/) + } + + AppTextField(modifier = modifier, value = text, placeholderValue = stringResource(id = R.string.hex), onValueChange = { + text = it + try { + onHexEdited(Color(android.graphics.Color.parseColor(it))) + } catch (e: Exception) { + e.printStackTrace() + } + }) +} \ No newline at end of file diff --git a/modules/common-ui-components/src/main/java/com/ankitsuda/rebound/ui/components/color_picker/ColorPicker1.kt b/modules/common-ui-components/src/main/java/com/ankitsuda/rebound/ui/components/color_picker/ColorPicker1.kt index bff73192..77067dbf 100644 --- a/modules/common-ui-components/src/main/java/com/ankitsuda/rebound/ui/components/color_picker/ColorPicker1.kt +++ b/modules/common-ui-components/src/main/java/com/ankitsuda/rebound/ui/components/color_picker/ColorPicker1.kt @@ -112,33 +112,6 @@ fun ColorPicker1( } } - -@Composable -private fun ColorHexInfo( - modifier: Modifier = Modifier, - selectedColor: Color, - onHexEdited: (Color) -> Unit -) { - var mSelectedColor by remember { - mutableStateOf(selectedColor) - } - var text by remember { - mutableStateOf("#" + mSelectedColor.toHexString().uppercase().drop(2)) - } - if (selectedColor != mSelectedColor) { - mSelectedColor = selectedColor - text = "#" + mSelectedColor.toHexString().uppercase().drop(2) - } - AppTextField(modifier = modifier, value = text, placeholderValue = stringResource(id = R.string.hex), onValueChange = { - text = it - try { - onHexEdited(Color(android.graphics.Color.parseColor(it))) - } catch (e: Exception) { - e.printStackTrace() - } - }) -} - private fun Color.toHexString(): String { val alphaString = (alpha * 255).toInt().toString(16).let { if (it.length == 1) "0$it" else it } val redString = (red * 255).toInt().toString(16).let { if (it.length == 1) "0$it" else it } diff --git a/modules/common-ui-components/src/main/java/com/ankitsuda/rebound/ui/components/color_picker/ColorPicker2.kt b/modules/common-ui-components/src/main/java/com/ankitsuda/rebound/ui/components/color_picker/ColorPicker2.kt new file mode 100644 index 00000000..a368777c --- /dev/null +++ b/modules/common-ui-components/src/main/java/com/ankitsuda/rebound/ui/components/color_picker/ColorPicker2.kt @@ -0,0 +1,97 @@ +/* + * 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.components.color_picker + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.dp +import com.godaddy.android.colorpicker.ClassicColorPicker +import com.godaddy.android.colorpicker.HsvColor + +@Composable +fun ColorPicker2( + modifier: Modifier = Modifier, + defaultColor: Color = Color.Red, + colorSelected: (Color) -> Unit +) { + var mColorFromHex by remember(key1 = defaultColor) { + mutableStateOf(defaultColor) + } + + var mColor by remember(key1 = defaultColor) { + mutableStateOf(defaultColor) + } + + LaunchedEffect(key1 = mColorFromHex, block = { + mColor = mColorFromHex + }) + + var colorHexInfoHeight by remember { + mutableStateOf(30.dp) + } + + BoxWithConstraints( + modifier = modifier + ) { + val minWidth = this.minWidth + Column( + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + key(mColorFromHex) { + ClassicColorPicker( + modifier = Modifier + .fillMaxWidth() + .height(minWidth), + color = mColorFromHex, + onColorChanged = { color: HsvColor -> + mColor = color.toColor() + colorSelected(color.toColor()) + } + ) + } + + Row( + verticalAlignment = Alignment.CenterVertically + ) { + Box( + Modifier + .height(colorHexInfoHeight) + .width(colorHexInfoHeight) + .background(mColor) + ) + Spacer(modifier = Modifier.width(16.dp)) + ColorHexInfo( + modifier = with(LocalDensity.current) { + Modifier.onGloballyPositioned { + colorHexInfoHeight = it.size.height.toDp() + } + }, + selectedColor = mColor, + onHexEdited = { + mColorFromHex = it + colorSelected(it) + } + ) + } + } + } +} \ No newline at end of file