From 86cadeddc4875f0c96b50e13b773e92966cded48 Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Thu, 11 Jan 2024 00:39:20 +0800 Subject: [PATCH] feat: update demo --- samples/shared/src/commonMain/kotlin/App.kt | 366 ++++++------------ .../shared/src/commonMain/kotlin/Resources.kt | 226 +++++++++++ 2 files changed, 339 insertions(+), 253 deletions(-) create mode 100644 samples/shared/src/commonMain/kotlin/Resources.kt diff --git a/samples/shared/src/commonMain/kotlin/App.kt b/samples/shared/src/commonMain/kotlin/App.kt index 9437558..9fff8d2 100644 --- a/samples/shared/src/commonMain/kotlin/App.kt +++ b/samples/shared/src/commonMain/kotlin/App.kt @@ -19,23 +19,21 @@ * * This file is created by fankes on 2023/11/5. */ +@file:OptIn(ExperimentalFoundationApi::class) import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState -import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -44,274 +42,136 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.highcapable.betterandroid.compose.extension.ui.ComponentPadding -import com.highcapable.flexiui.Colors import com.highcapable.flexiui.FlexiTheme -import com.highcapable.flexiui.blueColors import com.highcapable.flexiui.component.AreaBox import com.highcapable.flexiui.component.AreaColumn -import com.highcapable.flexiui.component.AutoCompleteOptions -import com.highcapable.flexiui.component.BackspaceTextField -import com.highcapable.flexiui.component.Button -import com.highcapable.flexiui.component.CheckBox -import com.highcapable.flexiui.component.DropdownList -import com.highcapable.flexiui.component.DropdownMenuItem -import com.highcapable.flexiui.component.PasswordTextField -import com.highcapable.flexiui.component.RadioButton -import com.highcapable.flexiui.component.ScrollableTabRow -import com.highcapable.flexiui.component.Slider -import com.highcapable.flexiui.component.Surface -import com.highcapable.flexiui.component.Switch -import com.highcapable.flexiui.component.Tab +import com.highcapable.flexiui.component.Icon +import com.highcapable.flexiui.component.IconDefaults +import com.highcapable.flexiui.component.NavigationBarItem +import com.highcapable.flexiui.component.NavigationBarRow +import com.highcapable.flexiui.component.PrimaryAppBar +import com.highcapable.flexiui.component.Scaffold +import com.highcapable.flexiui.component.SwitchItem import com.highcapable.flexiui.component.Text -import com.highcapable.flexiui.component.TextField -import com.highcapable.flexiui.defaultColors -import com.highcapable.flexiui.dynamicColors -import com.highcapable.flexiui.greenColors -import com.highcapable.flexiui.isDynamicColorsAvailable -import com.highcapable.flexiui.orangeColors -import com.highcapable.flexiui.pinkColors -import com.highcapable.flexiui.purpleColors -import com.highcapable.flexiui.redColors -import com.highcapable.flexiui.yellowColors +import com.highcapable.flexiui.resources.FlexiIcons import kotlinx.coroutines.launch -import kotlin.math.roundToInt + +@Stable +data class AppPreferences( + var darkMode: MutableState = mutableStateOf(false), + var followSystemDarkMode: MutableState = mutableStateOf(false) +) + +@Stable +private val Preferences = AppPreferences() @Composable fun App() { - val themeColor = remember { mutableStateOf(ThemeColors.first().second) } - FlexiTheme(colors = themeColor.value) { - Surface { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - AreaBox(modifier = Modifier.weight(0.82f)) { ContentView() } - Spacer(Modifier.padding(5.dp)) - AreaColumn( - modifier = Modifier.weight(0.18f), - style = AreaBox.style.copy(padding = ComponentPadding(3.dp)) - ) { TabPagerView() } - Spacer(Modifier.padding(10.dp)) - ThemeColorsView(themeColor) - } - } + FlexiTheme { + MainScreen() } } @Composable -private fun ContentView() { - val scrollState = rememberScrollState() - Column( - modifier = Modifier.fillMaxSize() - .verticalScroll(scrollState) - .padding(10.dp), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { - var greeting by remember { mutableStateOf("Hello World!") } - Text(text = greeting) - Spacer(Modifier.padding(15.dp)) - Button(onClick = { greeting = "Hello Jetpack Compose Multiplatform!" }) { - Text(text = "Greeting") - } - Spacer(Modifier.padding(15.dp)) - var input by remember { mutableStateOf("") } - TextField( - modifier = Modifier.width(TextFieldWidth), - value = input, - onValueChange = { input = it }, - placeholder = { Text(text = "Type something...") } - ) - Spacer(Modifier.padding(10.dp)) - var completion by remember { mutableStateOf("") } - TextField( - modifier = Modifier.width(TextFieldWidth), - value = completion, - onValueChange = { completion = it }, - placeholder = { Text(text = "Auto completion...") }, - singleLine = true, - completionValues = listOf( - "Compose", - "Compose World", - "Composable", - "Android", - "Jetpack", - "Jetpack Compose", - "Jetpack Compose Multiplatform" - ), - completionOptions = AutoCompleteOptions(checkCase = false, threshold = 1) - ) - Spacer(Modifier.padding(10.dp)) - var backspace by remember { mutableStateOf("") } - BackspaceTextField( - modifier = Modifier.width(TextFieldWidth), - value = backspace, - onValueChange = { backspace = it }, - placeholder = { Text(text = "Type or delete...") } - ) - Spacer(Modifier.padding(10.dp)) - var password by remember { mutableStateOf("") } - PasswordTextField( - modifier = Modifier.width(TextFieldWidth), - value = password, - onValueChange = { password = it }, - placeholder = { Text(text = "Enter password...") } - ) - Spacer(Modifier.padding(15.dp)) - var switchChecked by remember { mutableStateOf(true) } - Switch(checked = switchChecked, onCheckedChange = { switchChecked = it }) { - Text(modifier = Modifier.width(200.dp), text = "Switch Status: ${if (switchChecked) "Checked" else "Unchecked"}") - } - Spacer(Modifier.padding(15.dp)) - var boxChecked by remember { mutableStateOf(true) } - CheckBox(checked = boxChecked, onCheckedChange = { boxChecked = it }) { - Text(modifier = Modifier.width(210.dp), text = "CheckBox Status: ${if (boxChecked) "Checked" else "Unchecked"}") - } - Spacer(Modifier.padding(15.dp)) - Row { - var option1Seleted by remember { mutableStateOf(true) } - var option2Seleted by remember { mutableStateOf(false) } - fun switchOption(option1: Boolean) { - option1Seleted = option1 - option2Seleted = !option1 - } - RadioButton(option1Seleted, onClick = { switchOption(option1 = true) }) { - Text(text = "Option 1") - } - Spacer(Modifier.padding(15.dp)) - RadioButton(option2Seleted, onClick = { switchOption(option1 = false) }) { - Text(text = "Option 2") - } - } - Spacer(Modifier.padding(15.dp)) - var value by remember { mutableStateOf(50f) } - Text(text = "Current Value: ${value.roundToInt()}", modifier = Modifier.width(150.dp)) - Spacer(Modifier.padding(10.dp)) - Slider(value = value, onValueChange = { value = it }) - Spacer(Modifier.padding(15.dp)) - var stepValue by remember { mutableStateOf(25f) } - Text(text = "Current Value: ${stepValue.roundToInt()}", modifier = Modifier.width(150.dp)) - Spacer(Modifier.padding(10.dp)) - Slider(value = stepValue, onValueChange = { stepValue = it }, steps = 3) - Spacer(Modifier.padding(15.dp)) - val items = listOf("Item 1", "Item 2", "Item 3") - var expanded by remember { mutableStateOf(false) } - var curentItem by remember { mutableStateOf(items.first()) } - Text(text = "Choose an item following.") - Spacer(Modifier.padding(10.dp)) - DropdownList( - modifier = Modifier.width(DropdownListWidth), - expanded = expanded, - onExpandedChange = { expanded = it }, - text = { Text(text = curentItem) } - ) { - items.forEach { - DropdownMenuItem( - onClick = { - expanded = false - curentItem = it - }, - actived = curentItem == it - ) { Text(text = it) } - } - } - } -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -private fun TabPagerView() { - val pageCount = 10 +fun MainScreen() { + val pageCount = 2 val state = rememberPagerState(pageCount = { pageCount }) val scope = rememberCoroutineScope() - ScrollableTabRow( - selectedTabIndex = state.currentPage, - indicator = { TabIndicator(modifier = Modifier.pagerTabIndicatorOffset(state)) } + Scaffold( + appBar = { + PrimaryAppBar( + title = { Text("Flexi UI Demo") }, + actions = { + ActionIconButton( + onClick = { /* TODO */ } + ) { Icon(FlexiIcons.GitHub) } + } + ) + }, + navigationBar = { + NavigationBarRow( + arrangement = Arrangement.SpaceAround + ) { + NavigationBarItem( + selected = state.currentPage == 0, + onClick = { scope.launch { state.animateScrollToPage(page = 0) } }, + icon = { Icon(FlexiIcons.Home, style = IconDefaults.style(size = 24.dp)) }, + text = { Text("Home") } + ) + NavigationBarItem( + selected = state.currentPage == 1, + onClick = { scope.launch { state.animateScrollToPage(page = 1) } }, + icon = { Icon(FlexiIcons.Component, style = IconDefaults.style(size = 24.dp)) }, + text = { Text("Component") } + ) + } + } ) { - for (index in 0 until pageCount) - Tab( - selected = state.currentPage == index, - onClick = { scope.launch { state.animateScrollToPage(index) } }, - ) { Text(text = "Tab ${index + 1}") } + HorizontalPager( + modifier = Modifier.fillMaxSize(), + state = state, + ) { index -> + when (index) { + 0 -> MainHomePage() + 1 -> MainComponentPage() + } + } } - HorizontalPager( - modifier = Modifier.fillMaxSize(), - state = state, - ) { index -> Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Text(text = "Page ${index + 1}") } } } @Composable -private fun ThemeColorsView(themeColor: MutableState) { - Text(text = "Here are some theme color tests.") - Spacer(Modifier.padding(10.dp)) - var showChooser by remember { mutableStateOf(false) } - var choosedColorName by remember { mutableStateOf(ThemeColors.first().first) } - var choosedColor by remember { mutableStateOf(ThemeColors.first().second) } - themeColor.value = choosedColor - Row { - DropdownList( - modifier = Modifier.width(DropdownListWidth), - expanded = showChooser, - onExpandedChange = { showChooser = it }, - text = { Text(text = choosedColorName) } - ) { - ThemeColors.forEachIndexed { index, (name, colors) -> - @Composable - fun createItem(name: String, colors: Colors) = - DropdownMenuItem( - onClick = { - showChooser = false - choosedColorName = name - choosedColor = colors - }, - actived = choosedColorName == name - ) { Text(text = name) } - if (isDynamicColorsAvailable() && index == 2) - DynamicColors.forEach { (name, colors) -> createItem(name, colors) } - else createItem(name, colors) - } +fun MainHomePage() { + Column(modifier = Modifier.fillMaxSize()) { + AreaBox(modifier = Modifier.fillMaxWidth()) { + Text("Flexi UI is a flexible and useful UI component library.") + } + PrimarySpacer() + AreaColumn(modifier = Modifier.fillMaxWidth()) { + var darkMode by remember { Preferences.darkMode } + var followSystemDarkMode by remember { Preferences.followSystemDarkMode } + SecondaryText("Theme Style") + PrimarySpacer() + SwitchItem( + checked = darkMode, + onCheckedChange = { darkMode = it } + ) { Text("Enable night mode") } + SecondarySpacer() + SecondaryText("Manually switch the current theme to night mode.") + PrimarySpacer() + SwitchItem( + checked = followSystemDarkMode, + onCheckedChange = { followSystemDarkMode = it } + ) { Text("Follow system night mode") } + SecondarySpacer() + SecondaryText("Follow the system theme to switch day and night mode.") } - Spacer(modifier = Modifier.padding(5.dp)) - Button(onClick = { - choosedColorName = ThemeColors.first().first - choosedColor = ThemeColors.first().second - }) { Text(text = "Reset") } } } -private val DynamicColors - @Composable - @ReadOnlyComposable - get() = listOf( - "Dynamic" to dynamicColors(), - "Dynamic (Dark)" to dynamicColors(darkMode = true), - "Dynamic (Black)" to dynamicColors(darkMode = true, blackDarkMode = true) +@Composable +fun MainComponentPage() { + // TODO: To be implemented. + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { Text("To be implemented.") } +} + +@Composable +private fun PrimarySpacer() { + Spacer(modifier = Modifier.height(10.dp)) +} + +@Composable +private fun SecondarySpacer() { + Spacer(modifier = Modifier.height(5.dp)) +} + +@Composable +private fun SecondaryText(text: String) { + Text( + text = text, + color = FlexiTheme.colors.textSecondary, + style = FlexiTheme.typography.secondary ) - -private val ThemeColors = listOf( - "Default" to defaultColors(), - "Default (Dark)" to defaultColors(darkMode = true), - "Default (Black)" to defaultColors(darkMode = true, blackDarkMode = true), - "Red" to redColors(), - "Red (Dark)" to redColors(darkMode = true), - "Red (Black)" to redColors(darkMode = true, blackDarkMode = true), - "Pink" to pinkColors(), - "Pink (Dark)" to pinkColors(darkMode = true), - "Pink (Black)" to pinkColors(darkMode = true, blackDarkMode = true), - "Purple" to purpleColors(), - "Purple (Dark)" to purpleColors(darkMode = true), - "Purple (Black)" to purpleColors(darkMode = true, blackDarkMode = true), - "Green" to greenColors(), - "Green (Dark)" to greenColors(darkMode = true), - "Green (Black)" to greenColors(darkMode = true, blackDarkMode = true), - "Orange" to orangeColors(), - "Orange (Dark)" to orangeColors(darkMode = true), - "Orange (Black)" to orangeColors(darkMode = true, blackDarkMode = true), - "Yellow" to yellowColors(), - "Yellow (Dark)" to yellowColors(darkMode = true), - "Yellow (Black)" to yellowColors(darkMode = true, blackDarkMode = true), - "Blue" to blueColors(), - "Blue (Dark)" to blueColors(darkMode = true), - "Blue (Black)" to blueColors(darkMode = true, blackDarkMode = true) -) - -private val TextFieldWidth = 180.dp -private val DropdownListWidth = 170.dp \ No newline at end of file +} \ No newline at end of file diff --git a/samples/shared/src/commonMain/kotlin/Resources.kt b/samples/shared/src/commonMain/kotlin/Resources.kt new file mode 100644 index 0000000..3f77e55 --- /dev/null +++ b/samples/shared/src/commonMain/kotlin/Resources.kt @@ -0,0 +1,226 @@ +/* + * Flexi UI - A flexible and useful UI component library. + * Copyright (C) 2019-2024 HighCapable + * https://github.com/BetterAndroid/FlexiUI + * + * Apache License Version 2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is created by fankes on 2024/1/10. + */ + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.PathFillType +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.graphics.StrokeCap +import androidx.compose.ui.graphics.StrokeJoin +import androidx.compose.ui.graphics.vector.path +import androidx.compose.ui.unit.dp +import com.highcapable.betterandroid.compose.extension.ui.ImageVector +import com.highcapable.flexiui.resources.FlexiIcons + +val FlexiIcons.GitHub by lazy { + ImageVector( + name = "github", + defaultWidth = 150.dp, + defaultHeight = 150.dp, + viewportWidth = 1024f, + viewportHeight = 1024f + ) { + path( + fill = SolidColor(Color.White), + fillAlpha = 1.0f, + strokeAlpha = 1.0f, + strokeLineWidth = 1.0f, + strokeLineCap = StrokeCap.Butt, + strokeLineJoin = StrokeJoin.Miter, + strokeLineMiter = 1.0f, + pathFillType = PathFillType.NonZero + ) { + moveTo(512f, 12.6f) + curveToRelative(-282.8f, 0f, -512f, 229.2f, -512f, 512f) + curveToRelative(0f, 226.2f, 146.7f, 418.1f, 350.1f, 485.8f) + curveToRelative(25.6f, 4.7f, 35f, -11.1f, 35f, -24.6f) + curveToRelative(0f, -12.2f, -0.5f, -52.5f, -0.7f, -95.3f) + curveToRelative(-142.5f, 31f, -172.5f, -60.4f, -172.5f, -60.4f) + curveToRelative(-23.3f, -59.2f, -56.8f, -74.9f, -56.8f, -74.9f) + curveToRelative(-46.5f, -31.8f, 3.5f, -31.1f, 3.5f, -31.1f) + curveToRelative(51.4f, 3.6f, 78.5f, 52.8f, 78.5f, 52.8f) + curveToRelative(45.7f, 78.3f, 119.8f, 55.6f, 149f, 42.6f) + curveToRelative(4.6f, -33.1f, 17.9f, -55.7f, 32.5f, -68.5f) + curveToRelative(-113.7f, -12.9f, -233.3f, -56.9f, -233.3f, -253f) + curveToRelative(0f, -55.9f, 20f, -101.6f, 52.8f, -137.4f) + curveToRelative(-5.3f, -12.9f, -22.8f, -65f, 5f, -135.5f) + curveToRelative(0f, 0f, 43f, -13.8f, 140.8f, 52.5f) + curveToRelative(40.8f, -11.4f, 84.6f, -17f, 128.2f, -17.2f) + curveToRelative(43.5f, 0.2f, 87.3f, 5.9f, 128.3f, 17.2f) + curveToRelative(97.7f, -66.2f, 140.6f, -52.5f, 140.6f, -52.5f) + curveToRelative(27.9f, 70.5f, 10.3f, 122.6f, 5f, 135.5f) + curveToRelative(32.8f, 35.8f, 52.7f, 81.5f, 52.7f, 137.4f) + curveToRelative(0f, 196.6f, -119.8f, 239.9f, -233.8f, 252.6f) + curveToRelative(18.4f, 15.9f, 34.7f, 47f, 34.7f, 94.8f) + curveToRelative(0f, 68.5f, -0.6f, 123.6f, -0.6f, 140.5f) + curveToRelative(0f, 13.6f, 9.2f, 29.6f, 35.2f, 24.6f) + curveToRelative(203.3f, -67.8f, 349.9f, -259.6f, 349.9f, -485.8f) + curveToRelative(0f, -282.8f, -229.2f, -512f, -512f, -512f) + close() + } + } +} + +val FlexiIcons.Home by lazy { + ImageVector( + name = "home", + defaultWidth = 50.dp, + defaultHeight = 50.dp, + viewportWidth = 1024f, + viewportHeight = 1024f + ) { + path( + fill = SolidColor(Color.White), + fillAlpha = 1.0f, + strokeAlpha = 1.0f, + strokeLineWidth = 1.0f, + strokeLineCap = StrokeCap.Butt, + strokeLineJoin = StrokeJoin.Miter, + strokeLineMiter = 1.0f, + pathFillType = PathFillType.NonZero + ) { + moveTo(900.7f, 430.9f) + lineToRelative(-330.4f, -308f) + curveToRelative(-16.7f, -19f, -40.8f, -30f, -66.4f, -30f) + curveToRelative(-25.2f, 0f, -49.3f, 10.8f, -65.3f, 28.9f) + lineTo(120.5f, 430.8f) + curveToRelative(-15.9f, 16.3f, -20.5f, 39.8f, -11.7f, 60.8f) + curveToRelative(8.8f, 21f, 29.2f, 34.1f, 51.9f, 34.1f) + lineToRelative(28.7f, 0f) + lineToRelative(0f, 314.1f) + curveToRelative(0f, 48.7f, 39f, 88.3f, 87.7f, 88.3f) + lineToRelative(136.6f, 0f) + curveToRelative(17.7f, 0f, 33.5f, -14.3f, 33.5f, -32f) + lineTo(447.1f, 687f) + curveToRelative(0f, -8.9f, 5.8f, -16.8f, 14.7f, -16.8f) + lineToRelative(96.4f, 0f) + curveToRelative(8.9f, 0f, 15.7f, 8f, 15.7f, 16.8f) + lineToRelative(0f, 209f) + curveToRelative(0f, 17.8f, 14.8f, 32f, 32.5f, 32f) + lineToRelative(136.6f, 0f) + curveToRelative(48.7f, 0f, 88.6f, -39.5f, 88.6f, -88.3f) + lineToRelative(0f, -314.1f) + lineToRelative(28.5f, 0f) + curveToRelative(22.6f, 0f, 43f, -13.1f, 51.8f, -34f) + curveTo(921f, 470.8f, 916.5f, 447.2f, 900.7f, 430.9f) + lineTo(900.7f, 430.9f) + lineTo(900.7f, 430.9f) + moveTo(900.7f, 430.9f) + lineTo(900.7f, 430.9f) + close() + } + } +} + +val FlexiIcons.Component by lazy { + ImageVector( + name = "component", + defaultWidth = 48.dp, + defaultHeight = 48.dp, + viewportWidth = 48f, + viewportHeight = 48f + ) { + path( + fill = SolidColor(Color.White), + fillAlpha = 1.0f, + stroke = SolidColor(Color.White), + strokeAlpha = 1.0f, + strokeLineWidth = 4f, + strokeLineCap = StrokeCap.Butt, + strokeLineJoin = StrokeJoin.Round, + strokeLineMiter = 1.0f, + pathFillType = PathFillType.NonZero + ) { + moveTo(18f, 6f) + horizontalLineTo(8f) + curveTo(6.895f, 6f, 6f, 6.895f, 6f, 8f) + verticalLineTo(18f) + curveTo(6f, 19.105f, 6.895f, 20f, 8f, 20f) + horizontalLineTo(18f) + curveTo(19.105f, 20f, 20f, 19.105f, 20f, 18f) + verticalLineTo(8f) + curveTo(20f, 6.895f, 19.105f, 6f, 18f, 6f) + close() + } + path( + fill = SolidColor(Color.White), + fillAlpha = 1.0f, + stroke = SolidColor(Color.White), + strokeAlpha = 1.0f, + strokeLineWidth = 4f, + strokeLineCap = StrokeCap.Butt, + strokeLineJoin = StrokeJoin.Round, + strokeLineMiter = 1.0f, + pathFillType = PathFillType.NonZero + ) { + moveTo(18f, 28f) + horizontalLineTo(8f) + curveTo(6.895f, 28f, 6f, 28.895f, 6f, 30f) + verticalLineTo(40f) + curveTo(6f, 41.105f, 6.895f, 42f, 8f, 42f) + horizontalLineTo(18f) + curveTo(19.105f, 42f, 20f, 41.105f, 20f, 40f) + verticalLineTo(30f) + curveTo(20f, 28.895f, 19.105f, 28f, 18f, 28f) + close() + } + path( + fill = SolidColor(Color.White), + fillAlpha = 1.0f, + stroke = SolidColor(Color.White), + strokeAlpha = 1.0f, + strokeLineWidth = 4f, + strokeLineCap = StrokeCap.Butt, + strokeLineJoin = StrokeJoin.Round, + strokeLineMiter = 1.0f, + pathFillType = PathFillType.NonZero + ) { + moveTo(35f, 20f) + curveTo(38.866f, 20f, 42f, 16.866f, 42f, 13f) + curveTo(42f, 9.134f, 38.866f, 6f, 35f, 6f) + curveTo(31.134f, 6f, 28f, 9.134f, 28f, 13f) + curveTo(28f, 16.866f, 31.134f, 20f, 35f, 20f) + close() + } + path( + fill = SolidColor(Color.White), + fillAlpha = 1.0f, + stroke = SolidColor(Color.White), + strokeAlpha = 1.0f, + strokeLineWidth = 4f, + strokeLineCap = StrokeCap.Butt, + strokeLineJoin = StrokeJoin.Round, + strokeLineMiter = 1.0f, + pathFillType = PathFillType.NonZero + ) { + moveTo(40f, 28f) + horizontalLineTo(30f) + curveTo(28.895f, 28f, 28f, 28.895f, 28f, 30f) + verticalLineTo(40f) + curveTo(28f, 41.105f, 28.895f, 42f, 30f, 42f) + horizontalLineTo(40f) + curveTo(41.105f, 42f, 42f, 41.105f, 42f, 40f) + verticalLineTo(30f) + curveTo(42f, 28.895f, 41.105f, 28f, 40f, 28f) + close() + } + } +} \ No newline at end of file