feat: update demo

This commit is contained in:
2024-01-11 00:39:20 +08:00
parent 28d442bb2c
commit 86cadeddc4
2 changed files with 339 additions and 253 deletions

View File

@@ -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<Boolean> = mutableStateOf(false),
var followSystemDarkMode: MutableState<Boolean> = 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<Colors>) {
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
}

View File

@@ -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()
}
}
}