Spotless and ktlint

This commit is contained in:
Sad Ellie 2024-02-15 22:04:46 +03:00
parent 8b21721f48
commit eb00d8a76e
232 changed files with 1852 additions and 1601 deletions

7
.editorconfig Normal file
View File

@ -0,0 +1,7 @@
# https://editorconfig.org/
# This configuration is used by ktlint when spotless invokes it
[*.{kt,kts}]
ij_kotlin_allow_trailing_comma=true
ij_kotlin_allow_trailing_comma_on_call_site=true
ktlint_function_naming_ignore_when_annotated_with=Composable, Test

View File

@ -0,0 +1,42 @@
<!--
~ Unitto is a calculator for Android
~ Copyright (c) 2024 Elshan Agaev
~
~ This program 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 program 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.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="spotlessApply" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="--init-script gradle/init.gradle.kts --no-configuration-cache" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="spotlessApply" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<ForceTestExec>false</ForceTestExec>
<method v="2" />
</configuration>
</component>

View File

@ -0,0 +1,42 @@
<!--
~ Unitto is a calculator for Android
~ Copyright (c) 2024 Elshan Agaev
~
~ This program 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 program 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.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="spotlessCheck" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="--init-script gradle/init.gradle.kts --no-configuration-cache" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="spotlessCheck" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<ForceTestExec>false</ForceTestExec>
<method v="2" />
</configuration>
</component>

View File

@ -76,14 +76,14 @@ internal fun ComponentActivity.App(prefs: AppPreferences?) {
dynamicThemeEnabled = prefs.enableDynamicTheme,
amoledThemeEnabled = prefs.enableAmoledTheme,
customColor = prefs.customColor.toColor(),
monetMode = prefs.monetMode
monetMode = prefs.monetMode,
)
}
Themmo(
themmoController = themmoController,
typography = TypographySystem,
animationSpec = tween(250)
animationSpec = tween(250),
) {
val backgroundColor = MaterialTheme.colorScheme.background
val isDarkThemeEnabled = remember(backgroundColor) { backgroundColor.luminance() < 0.5f }
@ -113,9 +113,9 @@ internal fun ComponentActivity.App(prefs: AppPreferences?) {
navController = navController,
themmoController = it,
startDestination = prefs.startingScreen,
openDrawer = { drawerScope.launch { drawerState.open() } }
openDrawer = { drawerScope.launch { drawerState.open() } },
)
}
},
)
DisposableEffect(isDarkThemeEnabled) {

View File

@ -68,7 +68,7 @@ internal class MainActivity : AppCompatActivity() {
LocalLocale provides locale,
LocalWindowSize provides calculateWindowSizeClass(this@MainActivity),
LocalNumberTypography provides numbersTypography,
LocalHapticPreference provides (prefs?.enableVibrations ?: true)
LocalHapticPreference provides (prefs?.enableVibrations ?: true),
) {
App(prefs)
}

View File

@ -18,6 +18,7 @@
package com.sadellie.unitto
import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.Intent
import android.os.Build
@ -26,6 +27,7 @@ import androidx.annotation.RequiresApi
@RequiresApi(Build.VERSION_CODES.N)
class UnittoTileService : TileService() {
@SuppressLint("StartActivityAndCollapseDeprecated")
override fun onClick() {
super.onClick()

View File

@ -31,7 +31,7 @@ class StartupBaselineProfile {
@Test
fun generate() = baselineProfileRule.collect(
packageName = "com.sadellie.unitto",
includeInStartupProfile = true
includeInStartupProfile = true,
) {
startActivityAndWait()
device.pressBack()

View File

@ -61,7 +61,7 @@ class StartupBenchmark {
fun startupFullyPrecompiled() = startup(CompilationMode.Full())
private fun startup(
compilationMode: CompilationMode
compilationMode: CompilationMode,
) = benchmarkRule.measureRepeated(
packageName = "com.sadellie.unitto",
metrics = listOf(StartupTimingMetric()),
@ -70,7 +70,7 @@ class StartupBenchmark {
startupMode = StartupMode.COLD,
setupBlock = {
pressHome()
}
},
) {
startActivityAndWait()
}

View File

@ -24,8 +24,10 @@ package com.sadellie.unitto.core.base
object OutputFormat {
// Never use engineering notation
const val PLAIN = 0
// Use format that a lower API returns
const val ALLOW_ENGINEERING = 1
// App will try it's best to use engineering notation
const val FORCE_ENGINEERING = 2
}

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.base
@Suppress("ObjectPropertyName")
@ -100,14 +102,14 @@ object Token {
val all by lazy {
listOf(
arsin, arcos, actan, sin, cos, tan, log, exp, ln
arsin, arcos, actan, sin, cos, tan, log, exp, ln,
).sortedByDescending { it.length }
}
val allWithOpeningBracket by lazy {
listOf(
arsinBracket, arcosBracket, actanBracket, sinBracket, cosBracket, tanBracket,
logBracket, expBracket, lnBracket
logBracket, expBracket, lnBracket,
)
}
}
@ -144,7 +146,7 @@ object Token {
Operator.multiply to listOf("*", ""),
Func.arsin to listOf("arsin"),
Func.arcos to listOf("arcos"),
Func.actan to listOf("actan")
Func.actan to listOf("actan"),
)
}
}

View File

@ -150,7 +150,12 @@ class TokenTest {
@Test
fun testSexyToUgly() {
listOf(
"", "÷", "×", "sin⁻¹", "cos⁻¹", "tan⁻¹"
"",
"÷",
"×",
"sin⁻¹",
"cos⁻¹",
"tan⁻¹",
).forEach {
assert(it in Token.sexyToUgly.keys)
}

View File

@ -83,7 +83,7 @@ fun calculateWindowSizeClass(activity: Activity): WindowSizeClass {
@Immutable
class WindowSizeClass(
val widthSizeClass: WindowWidthSizeClass,
val heightSizeClass: WindowHeightSizeClass
val heightSizeClass: WindowHeightSizeClass,
) {
companion object {
/**
@ -118,7 +118,7 @@ class WindowSizeClass(
supportedWidthSizeClasses: Set<WindowWidthSizeClass> =
WindowWidthSizeClass.DefaultSizeClasses,
supportedHeightSizeClasses: Set<WindowHeightSizeClass> =
WindowHeightSizeClass.DefaultSizeClasses
WindowHeightSizeClass.DefaultSizeClasses,
): WindowSizeClass {
val windowWidthSizeClass =
WindowWidthSizeClass.fromWidth(size.width, density, supportedWidthSizeClasses)
@ -225,7 +225,9 @@ value class WindowWidthSizeClass private constructor(private val value: Int) :
/** Calculates the [WindowWidthSizeClass] for a given [width] */
internal fun fromWidth(width: Dp): WindowWidthSizeClass {
return fromWidth(
with(defaultDensity) { width.toPx() }, defaultDensity, DefaultSizeClasses
with(defaultDensity) { width.toPx() },
defaultDensity,
DefaultSizeClasses,
)
}
@ -236,7 +238,7 @@ value class WindowWidthSizeClass private constructor(private val value: Int) :
internal fun fromWidth(
width: Float,
density: Density,
supportedSizeClasses: Set<WindowWidthSizeClass>
supportedSizeClasses: Set<WindowWidthSizeClass>,
): WindowWidthSizeClass {
require(width >= 0) { "Width must not be negative" }
require(supportedSizeClasses.isNotEmpty()) { "Must support at least one size class" }
@ -323,7 +325,9 @@ value class WindowHeightSizeClass private constructor(private val value: Int) :
/** Calculates the [WindowHeightSizeClass] for a given [height] */
internal fun fromHeight(height: Dp): WindowHeightSizeClass {
return fromHeight(
with(defaultDensity) { height.toPx() }, defaultDensity, DefaultSizeClasses
with(defaultDensity) { height.toPx() },
defaultDensity,
DefaultSizeClasses,
)
}
@ -334,7 +338,7 @@ value class WindowHeightSizeClass private constructor(private val value: Int) :
internal fun fromHeight(
height: Float,
density: Density,
supportedSizeClasses: Set<WindowHeightSizeClass>
supportedSizeClasses: Set<WindowHeightSizeClass>,
): WindowHeightSizeClass {
require(height >= 0) { "Width must not be negative" }
require(supportedSizeClasses.isNotEmpty()) { "Must support at least one size class" }

View File

@ -44,16 +44,22 @@ fun NavGraphBuilder.unittoComposable(
route: String,
arguments: List<NamedNavArgument> = emptyList(),
deepLinks: List<NavDeepLink> = emptyList(),
enterTransition: (@JvmSuppressWildcards
AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? = { unittoFadeIn() },
exitTransition: (@JvmSuppressWildcards
AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? = { unittoFadeOut() },
popEnterTransition: (@JvmSuppressWildcards
AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =
enterTransition,
popExitTransition: (@JvmSuppressWildcards
AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =
exitTransition,
enterTransition: (
@JvmSuppressWildcards
AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?
)? = { unittoFadeIn() },
exitTransition: (
@JvmSuppressWildcards
AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?
)? = { unittoFadeOut() },
popEnterTransition: (
@JvmSuppressWildcards
AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?
)? = enterTransition,
popExitTransition: (
@JvmSuppressWildcards
AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?
)? = exitTransition,
content: @Composable AnimatedContentScope.(NavBackStackEntry) -> Unit,
): Unit = composable(
route = route,
@ -79,22 +85,26 @@ fun NavGraphBuilder.unittoStackedComposable(
enterTransition = {
slideInHorizontally(
animationSpec = unittoEnterTween(),
initialOffsetX = { (it * 0.2f).toInt() }) + unittoFadeIn()
initialOffsetX = { (it * 0.2f).toInt() },
) + unittoFadeIn()
},
exitTransition = {
slideOutHorizontally(
animationSpec = unittoExitTween(),
targetOffsetX = { -(it * 0.2f).toInt() }) + unittoFadeOut()
targetOffsetX = { -(it * 0.2f).toInt() },
) + unittoFadeOut()
},
popEnterTransition = {
slideInHorizontally(
animationSpec = unittoEnterTween(),
initialOffsetX = { -(it * 0.2f).toInt() }) + unittoFadeIn()
initialOffsetX = { -(it * 0.2f).toInt() },
) + unittoFadeIn()
},
popExitTransition = {
slideOutHorizontally(
animationSpec = unittoExitTween(),
targetOffsetX = { (it * 0.2f).toInt() }) + unittoFadeOut()
targetOffsetX = { (it * 0.2f).toInt() },
) + unittoFadeOut()
},
content = content,
)
@ -128,7 +138,7 @@ fun NavGraphBuilder.unittoNavigation(
exitTransition = exitTransition,
popEnterTransition = popEnterTransition,
popExitTransition = popExitTransition,
builder = builder
builder = builder,
)
private const val ENTER_DURATION = 350

View File

@ -48,7 +48,7 @@ suspend fun Context.pushDynamicShortcut(
val shortcutCompat = shortcutInfoCompat(
context = context,
route = drawerItem.graph,
shortcut = shortcut
shortcut = shortcut,
)
kotlin.runCatching {
@ -71,7 +71,7 @@ fun Context.addShortcut(
val shortcutCompat = shortcutInfoCompat(
context = context,
route = drawerItem.graph,
shortcut = shortcut
shortcut = shortcut,
)
val shortCutIntent = ShortcutManagerCompat.createShortcutResultIntent(context, shortcutCompat)
@ -80,7 +80,7 @@ fun Context.addShortcut(
ShortcutManagerCompat.requestPinShortcut(
context,
shortcutCompat,
PendingIntent.getBroadcast(context, 0, shortCutIntent, FLAG_IMMUTABLE).intentSender
PendingIntent.getBroadcast(context, 0, shortCutIntent, FLAG_IMMUTABLE).intentSender,
)
} catch (e: Exception) {
showToast(context, e.message ?: "Error")
@ -101,8 +101,8 @@ private fun Context.shortcutInfoCompat(
Intent.ACTION_VIEW,
Uri.parse("app://com.sadellie.unitto/$route"),
context,
context.javaClass
)
context.javaClass,
),
)
.build()
}

View File

@ -50,7 +50,7 @@ fun Button(
border: BorderStroke? = null,
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: @Composable RowScope.() -> Unit
content: @Composable RowScope.() -> Unit,
) {
Surface(
modifier = modifier.squashable(
@ -58,7 +58,7 @@ fun Button(
onLongClick = onLongClick,
interactionSource = interactionSource,
cornerRadiusRange = 30..50,
enabled = enabled
enabled = enabled,
),
color = containerColor,
contentColor = contentColor,
@ -70,12 +70,12 @@ fun Button(
Modifier
.defaultMinSize(
minWidth = ButtonDefaults.MinWidth,
minHeight = ButtonDefaults.MinHeight
minHeight = ButtonDefaults.MinHeight,
)
.padding(contentPadding),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
content = content
content = content,
)
}
}

View File

@ -70,16 +70,16 @@ fun FilterChip(
.border(
width = 1.dp,
color = borderColor.value,
shape = FilterChipDefaults.shape
shape = FilterChipDefaults.shape,
)
.height(FilterChipDefaults.Height)
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = label,
style = MaterialTheme.typography.labelLarge,
color = if (isSelected) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant
color = if (isSelected) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant,
)
}
}
@ -100,17 +100,17 @@ fun AssistChip(
.border(
width = 1.dp,
color = MaterialTheme.colorScheme.outline,
shape = AssistChipDefaults.shape
shape = AssistChipDefaults.shape,
)
.height(32.dp)
.padding(horizontal = 8.dp),
verticalAlignment = Alignment.CenterVertically
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
modifier = Modifier.height(AssistChipDefaults.IconSize),
imageVector = imageVector,
contentDescription = contentDescription,
tint = MaterialTheme.colorScheme.onSurfaceVariant
tint = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
}
@ -121,7 +121,7 @@ fun PreviewAssistChip() {
AssistChip(
onClick = {},
imageVector = Icons.Default.Settings,
contentDescription = ""
contentDescription = "",
)
}

View File

@ -33,13 +33,13 @@ internal fun DrawerItem(
destination: DrawerItem,
icon: ImageVector,
selected: Boolean,
onClick: (DrawerItem) -> Unit
onClick: (DrawerItem) -> Unit,
) {
NavigationDrawerItem(
modifier = modifier,
label = { Text(stringResource(destination.name)) },
icon = { Icon(icon, stringResource(destination.name)) },
selected = selected,
onClick = { onClick(destination) }
onClick = { onClick(destination) },
)
}

View File

@ -43,8 +43,8 @@ fun Header(
start = 56.dp,
end = 16.dp,
top = 24.dp,
bottom = 12.dp
)
bottom = 12.dp,
),
) {
Text(
modifier = modifier
@ -53,6 +53,6 @@ fun Header(
.fillMaxWidth(),
text = text,
style = MaterialTheme.typography.titleSmall,
color = MaterialTheme.colorScheme.primary
color = MaterialTheme.colorScheme.primary,
)
}

View File

@ -64,15 +64,24 @@ fun BasicKeyboardButton(
Box(
modifier = modifier
.squashable(
onClick = { onClick(); vibrate() },
onLongClick = if (onLongClick != null) { { onLongClick(); vibrate() } } else null,
onClick = {
onClick()
vibrate()
},
onLongClick = if (onLongClick != null) {
{
onLongClick()
vibrate()
}
} else {
null
},
interactionSource = remember { MutableInteractionSource() },
cornerRadiusRange = 30..50,
animationSpec = tween(200)
animationSpec = tween(200),
)
.background(containerColor)
,
contentAlignment = Alignment.Center
.background(containerColor),
contentAlignment = Alignment.Center,
) {
Icon(
imageVector = icon,
@ -84,7 +93,7 @@ fun BasicKeyboardButton(
scaleX = contentHeight
scaleY = contentHeight
},
tint = iconColor
tint = iconColor,
)
}
}
@ -173,22 +182,25 @@ fun KeyboardButtonTertiary(
)
}
object KeyboardButtonToken {
/**
* Mostly for main button in portrait mode. Changes icon size inside.
*/
const val KeyboardButtonContentHeightTall = 1.1f
const val CONTENT_HEIGHT_TALL = 1.1f
/**
* Mostly for additional button in portrait mode. Changes icon size inside.
*/
const val KeyboardButtonContentHeightTallAdditional = 1.6f
const val CONTENT_HEIGHT_TALL_ADDITIONAL = 1.6f
/**
* Mostly for main button in landscape mode. Changes icon size inside.
*/
const val KeyboardButtonContentHeightShort = 1.3f
const val CONTENT_HEIGHT_SHORT = 1.3f
/**
* Mostly for additional button in landscape mode. Changes icon size inside.
*/
const val KeyboardButtonContentHeightShortAdditional = 1.1f
const val CONTENT_HEIGHT_SHORT_ADDITIONAL = 1.1f
}

View File

@ -49,7 +49,7 @@ fun KeypadFlow(
columns: Int,
@IntRange(0, 100) horizontalPadding: Int = 10,
@IntRange(0, 100) verticalPadding: Int = 10,
content: @Composable FlowRowScope.(width: Float, height: Float) -> Unit
content: @Composable FlowRowScope.(width: Float, height: Float) -> Unit,
) {
val height: Float = remember { (1f - verticalPadding / 100f) / rows }
val width: Float = remember { (1f - horizontalPadding / 100f) / columns }
@ -58,7 +58,7 @@ fun KeypadFlow(
modifier = modifier,
maxItemsInEachRow = columns,
horizontalArrangement = Arrangement.SpaceAround,
verticalArrangement = Arrangement.SpaceAround
verticalArrangement = Arrangement.SpaceAround,
) {
content(width, height)
}

View File

@ -57,12 +57,12 @@ fun ListItem(
.padding(start = 16.dp, end = 24.dp)
.heightIn(min = if (supportingContent == null) 56.dp else 72.dp),
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalAlignment = Alignment.CenterVertically
verticalAlignment = Alignment.CenterVertically,
) {
leadingContent?.let {
ProvideColor(
color = MaterialTheme.colorScheme.onSurfaceVariant,
content = it
content = it,
)
}
@ -70,20 +70,20 @@ fun ListItem(
ProvideStyle(
color = MaterialTheme.colorScheme.onSurface,
textStyle = MaterialTheme.typography.bodyLarge,
content = headlineContent
content = headlineContent,
)
supportingContent?.let {
ProvideStyle(
color = MaterialTheme.colorScheme.onSurfaceVariant,
textStyle = MaterialTheme.typography.bodyMedium,
content = it
content = it,
)
}
}
trailingContent?.let {
ProvideColor(
color = MaterialTheme.colorScheme.onSurfaceVariant,
content = it
content = it,
)
}
}
@ -106,10 +106,10 @@ fun ListItem(
imageVector = icon,
contentDescription = iconDescription,
modifier = Modifier.size(24.dp),
tint = MaterialTheme.colorScheme.onSurfaceVariant
tint = MaterialTheme.colorScheme.onSurfaceVariant,
)
},
trailingContent = trailing
trailingContent = trailing,
)
@Composable
@ -120,14 +120,14 @@ fun ListItem(
iconDescription: String = headlineText,
supportingText: String? = null,
switchState: Boolean,
onSwitchChange: (Boolean) -> Unit
onSwitchChange: (Boolean) -> Unit,
) = ListItem(
modifier = modifier
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(),
onClick = { onSwitchChange(!switchState) },
role = Role.Switch
role = Role.Switch,
),
headlineText = headlineText,
supportingText = supportingText,
@ -136,9 +136,9 @@ fun ListItem(
trailing = {
Switch(
checked = switchState,
onCheckedChange = { onSwitchChange(it) }
onCheckedChange = { onSwitchChange(it) },
)
}
},
)
@Preview
@ -152,7 +152,7 @@ fun PreviewListItem1() {
leadingContent = {
Icon(
imageVector = Icons.Default.Home,
contentDescription = null
contentDescription = null,
)
},
)
@ -171,7 +171,7 @@ fun PreviewListItem1() {
supportingText = "Support text support text support text support text",
modifier = Modifier,
trailing = {},
iconDescription = ""
iconDescription = "",
)
ListItem(

View File

@ -47,7 +47,7 @@ fun Modifier.squashable(
val cornerRadius: Int by animateIntAsState(
targetValue = if (isPressed) cornerRadiusRange.first else cornerRadiusRange.last,
animationSpec = animationSpec,
label = "Squashed animation"
label = "Squashed animation",
)
this
@ -58,7 +58,7 @@ fun Modifier.squashable(
interactionSource = interactionSource,
indication = rememberRipple(),
role = role,
enabled = enabled
enabled = enabled,
)
}
@ -75,7 +75,7 @@ fun Modifier.squashable(
val cornerRadius: Dp by animateDpAsState(
targetValue = if (isPressed) cornerRadiusRange.start else cornerRadiusRange.endInclusive,
animationSpec = animationSpec,
label = "Squashed animation"
label = "Squashed animation",
)
this
@ -86,6 +86,6 @@ fun Modifier.squashable(
interactionSource = interactionSource,
indication = rememberRipple(),
role = role,
enabled = enabled
enabled = enabled,
)
}

View File

@ -36,7 +36,7 @@ fun NavigateUpButton(onClick: () -> Unit) {
IconButton(onClick = onClick) {
Icon(
Icons.AutoMirrored.Outlined.ArrowBack,
contentDescription = stringResource(R.string.navigate_up_description)
contentDescription = stringResource(R.string.navigate_up_description),
)
}
}

View File

@ -73,7 +73,7 @@ class DrawerState(
initialValue = initialValue,
positionalThreshold = { distance -> distance * 0.5f },
velocityThreshold = { with(requireNotNull(density)) { 400.dp.toPx() } },
animationSpec = tween()
animationSpec = tween(),
)
val isOpen: Boolean
@ -89,10 +89,10 @@ class DrawerState(
suspend fun close() = anchoredDraggableState.animateTo(DrawerValue.Closed)
companion object {
internal fun Saver() =
internal fun saver() =
Saver<DrawerState, DrawerValue>(
save = { it.currentValue },
restore = { DrawerState(it) }
restore = { DrawerState(it) },
)
}
}
@ -101,7 +101,7 @@ class DrawerState(
fun rememberDrawerState(
initialValue: DrawerValue = DrawerValue.Closed,
): DrawerState {
return rememberSaveable(saver = DrawerState.Saver()) {
return rememberSaveable(saver = DrawerState.saver()) {
DrawerState(initialValue)
}
}
@ -124,17 +124,17 @@ fun NavigationDrawer(
PermanentDrawerSheet(
modifier = Modifier
.fillMaxHeight()
.verticalScroll(rememberScrollState())
.verticalScroll(rememberScrollState()),
) {
SheetContent(
mainTabs = mainTabs,
additionalTabs = additionalTabs,
currentDestination = currentDestination,
onItemClick = onItemClick
onItemClick = onItemClick,
)
}
},
content = content
content = content,
)
} else {
UnittoModalNavigationDrawer(
@ -143,19 +143,19 @@ fun NavigationDrawer(
ModalDrawerSheet(
modifier = Modifier
.fillMaxHeight()
.verticalScroll(rememberScrollState())
.verticalScroll(rememberScrollState()),
) {
SheetContent(
mainTabs = mainTabs,
additionalTabs = additionalTabs,
currentDestination = currentDestination,
onItemClick = onItemClick
onItemClick = onItemClick,
)
}
},
gesturesEnabled = gesturesEnabled,
state = state,
content = content
content = content,
)
}
}
@ -173,7 +173,7 @@ private fun UnittoModalNavigationDrawer(
val drawerScope = rememberCoroutineScope()
Box(
modifier = modifier.fillMaxSize()
modifier = modifier.fillMaxSize(),
) {
val drawerWidth = 360.dp
val drawerWidthPx = with(density) { drawerWidth.toPx() }
@ -186,7 +186,7 @@ private fun UnittoModalNavigationDrawer(
DraggableAnchors {
DrawerValue.Closed at minValue
DrawerValue.Open at maxValue
}
},
)
}
@ -202,7 +202,7 @@ private fun UnittoModalNavigationDrawer(
state = state.anchoredDraggableState,
orientation = Orientation.Horizontal,
enabled = gesturesEnabled or state.isOpen,
)
),
)
Scrim(
@ -210,7 +210,9 @@ private fun UnittoModalNavigationDrawer(
onClose = { if (gesturesEnabled) drawerScope.launch { state.close() } },
fraction = {
fraction(
minValue, maxValue, state.anchoredDraggableState.requireOffset()
minValue,
maxValue,
state.anchoredDraggableState.requireOffset(),
)
},
)
@ -224,14 +226,14 @@ private fun UnittoModalNavigationDrawer(
.anchoredDraggableState
.requireOffset()
.roundToInt(),
y = 0
y = 0,
)
}
.anchoredDraggable(
state = state.anchoredDraggableState,
orientation = Orientation.Horizontal,
enabled = gesturesEnabled or state.isOpen,
)
),
) {
drawerContent()
}
@ -254,7 +256,7 @@ private fun Scrim(
Canvas(
Modifier
.fillMaxSize()
.then(dismissDrawer)
.then(dismissDrawer),
) {
drawRect(color, alpha = fraction())
}
@ -266,12 +268,12 @@ private fun fraction(a: Float, b: Float, pos: Float) =
@Preview(
backgroundColor = 0xFFC8F7D4,
showBackground = true,
device = "spec:width=320dp,height=500dp,dpi=320"
device = "spec:width=320dp,height=500dp,dpi=320",
)
@Preview(
backgroundColor = 0xFFC8F7D4,
showBackground = true,
device = "spec:width=440dp,height=500dp,dpi=440"
device = "spec:width=440dp,height=500dp,dpi=440",
)
@Composable
private fun PreviewUnittoModalNavigationDrawerClose() {
@ -290,11 +292,11 @@ private fun PreviewUnittoModalNavigationDrawerClose() {
Column {
Text(text = "Content")
Button(
onClick = { corScope.launch { drawerState.open() } }
onClick = { corScope.launch { drawerState.open() } },
) {
Text(text = "BUTTON")
}
}
}
},
)
}

View File

@ -81,12 +81,12 @@ fun PagedIsland(
corScope.launch {
pagerState.animateScrollToPage(
// Animate to first page if target page is out of bounds
if (targetPage >= pagerState.pageCount) 0 else targetPage
if (targetPage >= pagerState.pageCount) 0 else targetPage,
)
}
}
.background(backgroundColor)
.padding(16.dp)
.padding(16.dp),
) {
Row(
modifier = Modifier
@ -105,7 +105,7 @@ fun PagedIsland(
.fillMaxWidth(),
verticalAlignment = Alignment.Top,
state = pagerState,
pageContent = { page -> pageContent(page % pageCount) }
pageContent = { page -> pageContent(page % pageCount) },
)
}
}

View File

@ -52,8 +52,11 @@ fun PortraitLandscape(
.weight(1f)
.fillMaxSize()
.padding(
it.maxWidth * 0.015f, 0.dp,
it.maxHeight * 0.03f, it.maxHeight * 0.03f)
it.maxWidth * 0.015f,
0.dp,
it.maxHeight * 0.03f,
it.maxHeight * 0.03f,
)
content1(contentModifier)
content2(contentModifier)
}

View File

@ -41,10 +41,10 @@ fun ScaffoldWithLargeTopBar(
title: String,
navigationIcon: @Composable () -> Unit,
actions: @Composable RowScope.() -> Unit = {},
content: @Composable (PaddingValues) -> Unit
content: @Composable (PaddingValues) -> Unit,
) {
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(
rememberTopAppBarState()
rememberTopAppBarState(),
)
Scaffold(
modifier = Modifier
@ -56,9 +56,9 @@ fun ScaffoldWithLargeTopBar(
},
navigationIcon = navigationIcon,
scrollBehavior = scrollBehavior,
actions = actions
actions = actions,
)
},
content = content
content = content,
)
}

View File

@ -59,7 +59,7 @@ fun ScaffoldWithTopBar(
floatingActionButton: @Composable () -> Unit = {},
floatingActionButtonPosition: FabPosition = FabPosition.End,
scrollBehavior: TopAppBarScrollBehavior? = null,
content: @Composable (PaddingValues) -> Unit
content: @Composable (PaddingValues) -> Unit,
) {
Scaffold(
modifier = modifier,
@ -67,7 +67,7 @@ fun ScaffoldWithTopBar(
AnimatedVisibility(
visible = LocalWindowSize.current.heightSizeClass > WindowHeightSizeClass.Compact,
enter = slideInVertically() + fadeIn(),
exit = slideOutVertically() + fadeOut()
exit = slideOutVertically() + fadeOut(),
) {
CenterAlignedTopAppBar(
title = title,
@ -84,6 +84,6 @@ fun ScaffoldWithTopBar(
},
floatingActionButton = floatingActionButton,
floatingActionButtonPosition = floatingActionButtonPosition,
content = content
content = content,
)
}

View File

@ -109,7 +109,7 @@ fun SearchBar(
modifier = modifier
.windowInsetsPadding(TopAppBarDefaults.windowInsets)
.height(height),
contentAlignment = Alignment.Center
contentAlignment = Alignment.Center,
) {
Row(
modifier = Modifier
@ -121,10 +121,9 @@ fun SearchBar(
.fillMaxWidth()
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp)
horizontalArrangement = Arrangement.spacedBy(16.dp),
) {
ProvideColor(MaterialTheme.colorScheme.onSurface) {
NavigateButton { if (notEmpty) clear() else navigateUp() }
SearchTextField(
@ -135,7 +134,7 @@ fun SearchBar(
value = query,
placeholder = stringResource(R.string.search_text_field_placeholder),
onValueChange = onQueryChange,
onSearch = onSearch
onSearch = onSearch,
)
ClearButton(notEmpty, ::clear)
@ -152,7 +151,7 @@ private fun SearchTextField(
value: TextFieldValue,
placeholder: String,
onValueChange: (TextFieldValue) -> Unit,
onSearch: KeyboardActionScope.() -> Unit
onSearch: KeyboardActionScope.() -> Unit,
) {
BasicTextField(
modifier = modifier,
@ -171,33 +170,33 @@ private fun SearchTextField(
modifier = Modifier.alpha(0.7f),
text = placeholder,
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurface
color = MaterialTheme.colorScheme.onSurface,
)
}
}
},
)
}
@Composable
private fun SearchButton(
onClick: () -> Unit
onClick: () -> Unit,
) {
SearchBarIconButton(onClick) {
Icon(
imageVector = Icons.Default.Search,
contentDescription = stringResource(R.string.search_button_description)
contentDescription = stringResource(R.string.search_button_description),
)
}
}
@Composable
private fun NavigateButton(
onClick: () -> Unit
onClick: () -> Unit,
) {
SearchBarIconButton(onClick) {
Icon(
imageVector = Icons.AutoMirrored.Outlined.ArrowBack,
contentDescription = stringResource(R.string.navigate_up_description)
contentDescription = stringResource(R.string.navigate_up_description),
)
}
}
@ -205,17 +204,17 @@ private fun NavigateButton(
@Composable
private fun ClearButton(
visible: Boolean,
onClick: () -> Unit
onClick: () -> Unit,
) {
AnimatedVisibility(
visible = visible,
enter = fadeIn(),
exit = fadeOut()
exit = fadeOut(),
) {
SearchBarIconButton(onClick) {
Icon(
imageVector = Icons.Outlined.Clear,
contentDescription = stringResource(R.string.clear_input_description)
contentDescription = stringResource(R.string.clear_input_description),
)
}
}
@ -224,7 +223,7 @@ private fun ClearButton(
@Composable
fun SearchBarIconButton(
onClick: () -> Unit,
content: @Composable () -> Unit
content: @Composable () -> Unit,
) {
Box(
modifier = Modifier
@ -236,10 +235,10 @@ fun SearchBarIconButton(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(
bounded = false,
radius = 20.dp
)
radius = 20.dp,
),
contentAlignment = Alignment.Center
),
contentAlignment = Alignment.Center,
) {
content()
}
@ -259,6 +258,6 @@ fun UnittoSearchBarPreview() {
query = TextFieldValue("test"),
onQueryChange = {},
navigateUp = {},
scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(),
)
}

View File

@ -41,29 +41,29 @@ import com.sadellie.unitto.core.base.R
fun SearchPlaceholder(
onButtonClick: () -> Unit,
supportText: String,
buttonLabel: String
buttonLabel: String,
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp)
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
Icon(
imageVector = Icons.Default.SearchOff,
contentDescription = stringResource(R.string.no_results_description),
modifier = Modifier.size(48.dp)
modifier = Modifier.size(48.dp),
)
Text(
text = stringResource(R.string.no_results_label),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyLarge
style = MaterialTheme.typography.bodyLarge,
)
Text(
text = supportText,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodySmall
style = MaterialTheme.typography.bodySmall,
)
ElevatedButton(onClick = onButtonClick) {
Text(text = buttonLabel)

View File

@ -47,14 +47,14 @@ import androidx.compose.ui.unit.dp
@Composable
fun SegmentedButtonsRow(
modifier: Modifier = Modifier,
content: @Composable RowScope.() -> Unit
content: @Composable RowScope.() -> Unit,
) {
Row(
modifier
.width(IntrinsicSize.Max)
.height(40.dp)
.clip(CircleShape)
.border(1.dp, MaterialTheme.colorScheme.outline, CircleShape)
.border(1.dp, MaterialTheme.colorScheme.outline, CircleShape),
) {
content()
}
@ -66,7 +66,7 @@ fun RowScope.SegmentedButton(
label: String,
onClick: () -> Unit,
selected: Boolean,
icon: ImageVector? = null
icon: ImageVector? = null,
) {
val containerColor =
if (selected) MaterialTheme.colorScheme.secondaryContainer else MaterialTheme.colorScheme.surface
@ -77,9 +77,9 @@ fun RowScope.SegmentedButton(
shape = RectangleShape,
colors = ButtonDefaults.outlinedButtonColors(
containerColor = containerColor,
contentColor = contentColorFor(containerColor)
contentColor = contentColorFor(containerColor),
),
contentPadding = PaddingValues(horizontal = 12.dp)
contentPadding = PaddingValues(horizontal = 12.dp),
) {
if (icon != null) {
Crossfade(selected, label = "Selected state") {

View File

@ -67,14 +67,14 @@ internal fun ColumnScope.SheetContent(
modifier = Modifier.clickable(
interactionSource = interactionSource,
indication = null,
onClick = { showHello = true }
)
onClick = { showHello = true },
),
) { hello ->
Text(
text = if (hello) stringResource(R.string.hello_label) else stringResource(R.string.app_name),
modifier = Modifier.padding(horizontal = 28.dp, vertical = 24.dp),
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.primary
color = MaterialTheme.colorScheme.primary,
)
}
@ -85,7 +85,7 @@ internal fun ColumnScope.SheetContent(
destination = drawerItem,
icon = if (selected) drawerItem.selectedIcon else drawerItem.defaultIcon,
selected = selected,
onClick = onItemClick
onClick = onItemClick,
)
}
@ -98,7 +98,7 @@ internal fun ColumnScope.SheetContent(
destination = drawerItem,
icon = if (selected) drawerItem.selectedIcon else drawerItem.defaultIcon,
selected = selected,
onClick = onItemClick
onClick = onItemClick,
)
}
}
@ -119,7 +119,7 @@ private fun PreviewDrawerSheet() {
DrawerItem.Calculator,
),
currentDestination = DrawerItem.Calculator.start,
onItemClick = {}
onItemClick = {},
)
}
}

View File

@ -56,12 +56,12 @@ fun Slider(
value: Float,
valueRange: ClosedFloatingPointRange<Float>,
onValueChange: (Float) -> Unit,
onValueChangeFinished: (Float) -> Unit = {}
onValueChangeFinished: (Float) -> Unit = {},
) {
val animated = animateFloatAsState(
targetValue = value.roundToInt().toFloat(),
animationSpec = spring(),
label = "Thumb animation"
label = "Thumb animation",
)
Slider(
@ -81,14 +81,14 @@ private fun SquigglyTrack(
@FloatRange(0.0, 1.0) waveHeight: Float = 0.7f,
strokeWidth: Float = 15f,
filledColor: Color = MaterialTheme.colorScheme.primary,
unfilledColor: Color = MaterialTheme.colorScheme.surfaceVariant
unfilledColor: Color = MaterialTheme.colorScheme.surfaceVariant,
) {
val coroutineScope = rememberCoroutineScope()
var direct by remember { mutableFloatStateOf(waveHeight * (100f - strokeWidth * 2f) / 100f) }
val animatedDirect = animateFloatAsState(
targetValue = direct,
animationSpec = spring(stiffness = Spring.StiffnessLow),
label = "Track animation"
label = "Track animation",
)
LaunchedEffect(sliderState.value) {
@ -101,7 +101,7 @@ private fun SquigglyTrack(
Canvas(
modifier = Modifier
.fillMaxWidth()
.height(20.dp)
.height(20.dp),
) {
val width = size.width
val height = size.height
@ -114,7 +114,7 @@ private fun SquigglyTrack(
val path = Path().apply {
moveTo(
x = initialOffset,
y = height.times(0.5f)
y = height.times(0.5f),
)
val amount = ceil(width.div(eachWaveWidth))
@ -125,7 +125,7 @@ private fun SquigglyTrack(
dx1 = eachWaveWidth * 0.5f,
dy1 = height.times(peek),
dx2 = eachWaveWidth,
dy2 = 0f
dy2 = 0f,
)
}
}
@ -135,12 +135,12 @@ private fun SquigglyTrack(
left = 0f,
right = thumbPosition,
bottom = height,
clipOp = ClipOp.Intersect
clipOp = ClipOp.Intersect,
) {
drawPath(
path = path,
color = filledColor,
style = Stroke(strokeWidth, cap = StrokeCap.Round)
style = Stroke(strokeWidth, cap = StrokeCap.Round),
)
}
@ -149,7 +149,7 @@ private fun SquigglyTrack(
start = Offset(thumbPosition, height.times(0.5f)),
end = Offset(width, height.times(0.5f)),
strokeWidth = strokeWidth,
cap = StrokeCap.Round
cap = StrokeCap.Round,
)
}
}
@ -165,6 +165,6 @@ private fun PreviewNewSlider() {
com.sadellie.unitto.core.ui.common.Slider(
value = currentValue,
valueRange = 0f..16f,
onValueChange = { currentValue = it }
onValueChange = { currentValue = it },
)
}

View File

@ -70,7 +70,7 @@ fun Switch(
)
val thumbOffset = animateDpAsState(
targetValue = if (checked) ThumbPaddingEnd else ThumbPaddingStart,
label = "Thumb offset"
label = "Thumb offset",
)
Box(
@ -81,15 +81,15 @@ fun Switch(
enabled = true,
onClickLabel = null,
role = Role.Switch,
onClick = { onCheckedChange(!checked) }
onClick = { onCheckedChange(!checked) },
)
.background(trackColor.value, CircleShape)
.size(TrackWidth, TrackHeight)
.border(
TrackOutlineWidth,
borderColor(enabled, checked, colors),
CircleShape
)
CircleShape,
),
) {
Box(
modifier = Modifier
@ -100,7 +100,7 @@ fun Switch(
)
.align(Alignment.CenterStart)
.background(thumbColor.value, CircleShape)
.size(thumbSize.value)
.size(thumbSize.value),
)
}
}
@ -109,7 +109,7 @@ fun Switch(
private fun trackColor(
enabled: Boolean,
checked: Boolean,
colors: SwitchColors
colors: SwitchColors,
): Color =
if (enabled) {
if (checked) colors.checkedTrackColor else colors.uncheckedTrackColor
@ -121,7 +121,7 @@ private fun trackColor(
private fun thumbColor(
enabled: Boolean,
checked: Boolean,
colors: SwitchColors
colors: SwitchColors,
): Color =
if (enabled) {
if (checked) colors.checkedThumbColor else colors.uncheckedThumbColor
@ -133,7 +133,7 @@ private fun thumbColor(
private fun borderColor(
enabled: Boolean,
checked: Boolean,
colors: SwitchColors
colors: SwitchColors,
): Color =
if (enabled) {
if (checked) colors.checkedBorderColor else colors.uncheckedBorderColor
@ -156,6 +156,6 @@ fun PreviewPixelSwitch() {
var checked by remember { mutableStateOf(false) }
Switch(
checked = checked,
onCheckedChange = { checked = !checked }
onCheckedChange = { checked = !checked },
)
}

View File

@ -34,11 +34,11 @@ fun ColumnWithConstraints(
modifier: Modifier = Modifier,
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
content: @Composable (ColumnScope.(BoxWithConstraintsScope)-> Unit)
content: @Composable (ColumnScope.(BoxWithConstraintsScope) -> Unit),
) = BoxWithConstraints(modifier) {
Column(
verticalArrangement = verticalArrangement,
horizontalAlignment = horizontalAlignment
horizontalAlignment = horizontalAlignment,
) { content(this@BoxWithConstraints) }
}
@ -47,10 +47,10 @@ fun RowWithConstraints(
modifier: Modifier = Modifier,
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
verticalAlignment: Alignment.Vertical = Alignment.Top,
content: @Composable (RowScope.(BoxWithConstraintsScope)-> Unit)
content: @Composable (RowScope.(BoxWithConstraintsScope) -> Unit),
) = BoxWithConstraints(modifier) {
Row(
horizontalArrangement = horizontalArrangement,
verticalAlignment = verticalAlignment
verticalAlignment = verticalAlignment,
) { content(this@BoxWithConstraints) }
}

View File

@ -43,54 +43,6 @@ import androidx.compose.ui.unit.TextUnit
import kotlin.math.min
import kotlin.math.roundToInt
// HUGE performance drop. Don't use for buttons
///**
// * Composable function that automatically adjusts the text size to fit within given constraints using AnnotatedString, considering the ratio of line spacing to text size.
// *
// * Features:
// * Similar to AutoSizeText(String), with support for AnnotatedString.
// *
// * @param inlineContent a map storing composables that replaces certain ranges of the text, used to
// * insert composables into text layout. See [InlineTextContent].
// * @see AutoSizeText
// */
//@Composable
//internal fun AutoSizeText(
// text: AnnotatedString,
// modifier: Modifier = Modifier,
// minRatio: Float = 1f,
// maxTextSize: TextUnit = TextUnit.Unspecified,
// alignment: Alignment = Alignment.TopStart,
// overflow: TextOverflow = TextOverflow.Clip,
// softWrap: Boolean = true,
// maxLines: Int = Int.MAX_VALUE,
// minLines: Int = 1,
// inlineContent: Map<String, InlineTextContent> = mapOf(),
// onTextLayout: (TextLayoutResult) -> Unit = {},
// style: TextStyle = LocalTextStyle.current,
//) = AutoSizeTextStyleBox(
// modifier = modifier,
// text = text,
// maxTextSize = maxTextSize,
// maxLines = maxLines,
// minLines = minLines,
// softWrap = softWrap,
// style = style,
// minRatio = minRatio,
// alignment = alignment
//) {
// Text(
// text = text,
// overflow = overflow,
// softWrap = softWrap,
// maxLines = maxLines,
// minLines = minLines,
// inlineContent = inlineContent,
// onTextLayout = onTextLayout,
// style = LocalTextStyle.current,
// )
//}
/**
* [BoxWithConstraints] with [autoTextStyle] passed via [LocalTextStyle].
*
@ -122,11 +74,11 @@ internal fun AutoSizeTextStyleBox(
style: TextStyle,
minRatio: Float,
alignment: Alignment,
content: @Composable () -> Unit
content: @Composable () -> Unit,
) {
val density = LocalDensity.current
CompositionLocalProvider(
LocalDensity provides Density(density = density.density, fontScale = 1F)
LocalDensity provides Density(density = density.density, fontScale = 1F),
) {
BoxWithConstraints(
modifier = modifier,
@ -141,12 +93,12 @@ internal fun AutoSizeTextStyleBox(
style = style,
alignment = alignment,
density = density,
minRatio = minRatio
minRatio = minRatio,
)
CompositionLocalProvider(
value = LocalTextStyle.provides(autoTextStyle),
content = content
content = content,
)
}
}
@ -290,10 +242,11 @@ private fun <E> IntProgression.findElectedValue(
var high = last
while (low <= high) {
val mid = low + (high - low) / 2
if (shouldMoveBackward(transform(mid)))
if (shouldMoveBackward(transform(mid))) {
high = mid - 1
else
} else {
low = mid + 1
}
}
transform(high.coerceAtLeast(minimumValue = first))
}

View File

@ -27,5 +27,8 @@ import androidx.compose.ui.unit.isSpecified
internal fun Density.roundToPx(sp: TextUnit): Int = sp.roundToPx()
internal fun Density.toSp(px: Int): TextUnit = px.toSp()
internal fun Density.toIntSize(dpSize: DpSize): IntSize =
if (dpSize.isSpecified) IntSize(dpSize.width.roundToPx(), dpSize.height.roundToPx())
else IntSize.Zero
if (dpSize.isSpecified) {
IntSize(dpSize.width.roundToPx(), dpSize.height.roundToPx())
} else {
IntSize.Zero
}

View File

@ -67,7 +67,7 @@ fun DatePickerDialog(
BasicAlertDialog(
onDismissRequest = onDismiss,
modifier = modifier.wrapContentHeight(),
properties = DialogProperties(usePlatformDefaultWidth = false)
properties = DialogProperties(usePlatformDefaultWidth = false),
) {
Surface(
modifier = modifier
@ -83,15 +83,14 @@ fun DatePickerDialog(
Box(
modifier = Modifier
.align(Alignment.End)
.padding(_dialogButtonsPadding)
.padding(_dialogButtonsPadding),
) {
AlertDialogFlowRow(
mainAxisSpacing = _dialogButtonsMainAxisSpacing,
crossAxisSpacing = _dialogButtonsCrossAxisSpacing
crossAxisSpacing = _dialogButtonsCrossAxisSpacing,
) {
TextButton(
onClick = onDismiss
onClick = onDismiss,
) {
Text(text = dismissLabel)
}
@ -100,16 +99,17 @@ fun DatePickerDialog(
val millis = pickerState.selectedDateMillis ?: return@TextButton
val date = LocalDateTime.ofInstant(
Instant.ofEpochMilli(millis), ZoneId.systemDefault()
Instant.ofEpochMilli(millis),
ZoneId.systemDefault(),
)
onConfirm(
localDateTime
.withYear(date.year)
.withMonth(date.monthValue)
.withDayOfMonth(date.dayOfMonth)
.withDayOfMonth(date.dayOfMonth),
)
}
},
) {
Text(text = confirmLabel)
}
@ -125,7 +125,7 @@ fun DatePickerDialog(
private fun AlertDialogFlowRow(
mainAxisSpacing: Dp,
crossAxisSpacing: Dp,
content: @Composable () -> Unit
content: @Composable () -> Unit,
) {
Layout(content) { measurables, constraints ->
val sequences = mutableListOf<List<Placeable>>()
@ -193,14 +193,16 @@ private fun AlertDialogFlowRow(
val mainAxisPositions = IntArray(childrenMainAxisSizes.size) { 0 }
with(arrangement) {
arrange(
mainAxisLayoutSize, childrenMainAxisSizes,
layoutDirection, mainAxisPositions
mainAxisLayoutSize,
childrenMainAxisSizes,
layoutDirection,
mainAxisPositions,
)
}
placeables.forEachIndexed { j, placeable ->
placeable.place(
x = mainAxisPositions[j],
y = crossAxisPositions[i]
y = crossAxisPositions[i],
)
}
}

View File

@ -73,7 +73,7 @@ fun TimePickerDialog(
val pickerState = rememberTimePickerState(
initialHour = hour,
initialMinute = minute,
is24Hour = DateFormat.is24HourFormat(LocalContext.current)
is24Hour = DateFormat.is24HourFormat(LocalContext.current),
)
val configuration = LocalConfiguration.current
var showingPicker by rememberSaveable { mutableStateOf(true) }
@ -81,8 +81,8 @@ fun TimePickerDialog(
BasicAlertDialog(
onDismissRequest = onCancel,
properties = DialogProperties(
usePlatformDefaultWidth = false
)
usePlatformDefaultWidth = false,
),
) {
Surface(
shape = MaterialTheme.shapes.extraLarge,
@ -92,7 +92,7 @@ fun TimePickerDialog(
.height(IntrinsicSize.Min)
.background(
shape = MaterialTheme.shapes.extraLarge,
color = MaterialTheme.colorScheme.surface
color = MaterialTheme.colorScheme.surface,
),
) {
if (configuration.screenHeightDp > 400) {
@ -103,7 +103,7 @@ fun TimePickerDialog(
.fillMaxSize()
.semantics {
isTraversalGroup = true
}
},
) {
IconButton(
modifier = Modifier
@ -114,7 +114,8 @@ fun TimePickerDialog(
.size(64.dp, 72.dp)
.align(Alignment.BottomStart)
.zIndex(5f),
onClick = { showingPicker = !showingPicker }) {
onClick = { showingPicker = !showingPicker },
) {
val icon = if (showingPicker) {
Icons.Outlined.Keyboard
} else {
@ -122,21 +123,21 @@ fun TimePickerDialog(
}
Icon(
imageVector = icon,
contentDescription = stringResource(R.string.select_time_label)
contentDescription = stringResource(R.string.select_time_label),
)
}
}
}
Column(
modifier = Modifier.padding(24.dp),
horizontalAlignment = Alignment.CenterHorizontally
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 20.dp),
text = stringResource(R.string.select_time_label),
style = MaterialTheme.typography.labelMedium
style = MaterialTheme.typography.labelMedium,
)
if (showingPicker && configuration.screenHeightDp > 400) {
TimePicker(state = pickerState)
@ -146,14 +147,14 @@ fun TimePickerDialog(
Row(
modifier = Modifier
.height(40.dp)
.fillMaxWidth()
.fillMaxWidth(),
) {
Spacer(modifier = Modifier.weight(1f))
TextButton(
onClick = onCancel
onClick = onCancel,
) { Text(stringResource(R.string.cancel_label)) }
TextButton(
onClick = { onConfirm(pickerState.hour, pickerState.minute) }
onClick = { onConfirm(pickerState.hour, pickerState.minute) },
) { Text(confirmLabel) }
}
}

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("ktlint:standard:property-naming")
package com.sadellie.unitto.core.ui.common.icons.iconpack
import androidx.compose.ui.graphics.Color

View File

@ -32,15 +32,15 @@ import com.sadellie.unitto.core.base.Token
*/
internal class ExpressionClipboardManager(
private val formatterSymbols: FormatterSymbols,
private val clipboardManager: android.content.ClipboardManager
private val clipboardManager: android.content.ClipboardManager,
) : ClipboardManager {
override fun setText(annotatedString: AnnotatedString) = clipboardManager.setPrimaryClip(
ClipData.newPlainText(
PLAIN_TEXT_LABEL,
annotatedString
.text
.replace(Token.Digit.dot, formatterSymbols.fractional)
)
.replace(Token.Digit.dot, formatterSymbols.fractional),
),
)
override fun getText(): AnnotatedString? = clipboardManager.primaryClip?.let { primaryClip ->

View File

@ -22,7 +22,6 @@ import com.sadellie.unitto.core.base.Token
import kotlin.math.abs
fun String.fixCursor(pos: Int, grouping: String): Int {
if (isEmpty()) return pos
// Best position if we move cursor left
@ -75,7 +74,7 @@ private fun Int.isAtToken(str: String, token: String): Boolean {
return str
.substring(
startIndex = (this - checkBound).coerceAtLeast(0),
endIndex = (this + checkBound).coerceAtMost(str.length)
endIndex = (this + checkBound).coerceAtMost(str.length),
)
.contains(token)
}
@ -86,7 +85,6 @@ private fun Int.isAfterToken(str: String, token: String): Boolean {
.contains(token)
}
// This can also make [TextFieldValue.addTokens] better by checking tokens both ways. Needs more tests
fun String.tokenAfter(pos: Int): String {
Token.Func.allWithOpeningBracket.forEach {
@ -96,23 +94,6 @@ fun String.tokenAfter(pos: Int): String {
return substring(pos, (pos + 1).coerceAtMost(this.length))
}
//private fun String.numberNearby(cursor: Int): String {
// val text = this
//
// var aheadCursor = cursor
// var afterCursor = cursor
//
// while (text.tokenAhead(aheadCursor) in Token.Digit.allWithDot) {
// aheadCursor--
// }
//
// while (text.tokenAfter(afterCursor) in Token.Digit.allWithDot) {
// afterCursor++
// }
//
// return text.substring(aheadCursor, afterCursor)
//}
private fun Int.isBeforeToken(str: String, token: String): Boolean {
return str
.substring(this, (this + token.length).coerceAtMost(str.length))

View File

@ -30,13 +30,13 @@ class ExpressionTransformer(private val formatterSymbols: FormatterSymbols) : Vi
val formatted = text.text.formatExpression(formatterSymbols)
return TransformedText(
text = AnnotatedString(formatted),
offsetMapping = ExpressionMapping(text.text, formatted)
offsetMapping = ExpressionMapping(text.text, formatted),
)
}
inner class ExpressionMapping(
private val original: String,
private val transformed: String
private val transformed: String,
) : OffsetMapping {
// Called when entering text (on each text change)
// Basically moves cursor to the right position

View File

@ -49,7 +49,7 @@ fun FixedExpressionInputTextField(
val clipboardManager = FormattedExpressionClipboardManager(
formatterSymbols = formatterSymbols,
clipboardManager = LocalContext.current.getSystemService(Context.CLIPBOARD_SERVICE)
as android.content.ClipboardManager
as android.content.ClipboardManager,
)
CompositionLocalProvider(LocalClipboardManager provides clipboardManager) {
@ -57,7 +57,7 @@ fun FixedExpressionInputTextField(
modifier = Modifier
.horizontalScroll(rememberScrollState()) // Must be first
.clickable(onClick = onClick)
.then(modifier)
.then(modifier),
) {
Text(
modifier = Modifier.fillMaxWidth(),
@ -71,7 +71,7 @@ fun FixedExpressionInputTextField(
private class FormattedExpressionClipboardManager(
private val formatterSymbols: FormatterSymbols,
private val clipboardManager: android.content.ClipboardManager
private val clipboardManager: android.content.ClipboardManager,
) : ClipboardManager {
override fun getText(): AnnotatedString? = null
@ -81,8 +81,8 @@ private class FormattedExpressionClipboardManager(
PLAIN_TEXT_LABEL,
annotatedString
.text
.replace(formatterSymbols.grouping, "")
)
.replace(formatterSymbols.grouping, ""),
),
)
}
}

View File

@ -51,7 +51,7 @@ internal fun String.clearAndFilterNumberBase(): String {
}
fun String.formatExpression(
formatterSymbols: FormatterSymbols
formatterSymbols: FormatterSymbols,
): String {
var input = this
@ -84,7 +84,7 @@ fun String.formatExpression(
}
private fun String.formatNumber(
formatterSymbols: FormatterSymbols
formatterSymbols: FormatterSymbols,
): String {
val input = this
@ -114,7 +114,7 @@ private fun String.leaveLegalTokensOnly(legalTokens: List<String>): String {
val subs = streamOfTokens
.substring(
cursor,
(cursor + token.length).coerceAtMost(streamOfTokens.length)
(cursor + token.length).coerceAtMost(streamOfTokens.length),
)
if (subs == token) {
// Got a digit, see if there are other digits coming after

View File

@ -64,7 +64,7 @@ fun ExpressionTextField(
ExpressionClipboardManager(
formatterSymbols = formatterSymbols,
clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE)
as android.content.ClipboardManager
as android.content.ClipboardManager,
)
}
val expressionTransformer = remember(formatterSymbols) {
@ -72,7 +72,7 @@ fun ExpressionTextField(
}
CompositionLocalProvider(
LocalClipboardManager provides clipboardManager
LocalClipboardManager provides clipboardManager,
) {
AutoSizeTextField(
modifier = modifier,
@ -85,7 +85,7 @@ fun ExpressionTextField(
textStyle = LocalNumberTypography.current.displayLarge.copy(textColor),
visualTransformation = expressionTransformer,
cursorBrush = SolidColor(MaterialTheme.colorScheme.onSurfaceVariant),
minRatio = minRatio
minRatio = minRatio,
)
}
}
@ -110,7 +110,7 @@ fun NumberBaseTextField(
readOnly = readOnly,
textStyle = LocalNumberTypography.current.displayLarge.copy(textColor),
cursorBrush = SolidColor(MaterialTheme.colorScheme.onSurfaceVariant),
minRatio = minRatio
minRatio = minRatio,
)
}
@ -132,7 +132,7 @@ fun SimpleTextField(
readOnly = readOnly,
textStyle = LocalNumberTypography.current.displayLarge.copy(textColor),
cursorBrush = SolidColor(MaterialTheme.colorScheme.onSurfaceVariant),
minRatio = minRatio
minRatio = minRatio,
)
}
@ -174,7 +174,7 @@ private fun AutoSizeTextField(
softWrap = false,
style = textStyle,
minRatio = minRatio,
alignment = alignment
alignment = alignment,
) {
CompositionLocalProvider(
LocalTextInputService provides null,
@ -204,8 +204,8 @@ private fun AutoSizeTextField(
text = placeholder!!,
style = style.copy(
textAlign = TextAlign.End,
color = MaterialTheme.colorScheme.onSurface.copy(0.5f)
)
color = MaterialTheme.colorScheme.onSurface.copy(0.5f),
),
)
}
innerTextField()

View File

@ -62,8 +62,8 @@ fun OutlinedDecimalTextField(
visualTransformation = expressionFormatter,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Decimal,
imeAction = imeAction
imeAction = imeAction,
),
colors = colors
colors = colors,
)
}

View File

@ -30,7 +30,8 @@ fun TextFieldValue.addTokens(tokens: String): TextFieldValue {
Token.Operator.plus,
Token.Operator.multiply,
Token.Operator.divide,
Token.Operator.power -> {
Token.Operator.power,
-> {
if (ahead == Token.Operator.plus) return deleteAheadAndAdd(tokens)
if (ahead == Token.Operator.minus) return deleteAheadAndAdd(tokens)
if (ahead == Token.Operator.multiply) return deleteAheadAndAdd(tokens)
@ -50,7 +51,7 @@ fun TextFieldValue.addTokens(tokens: String): TextFieldValue {
return this.copy(
text = text.replaceRange(selection.start, selection.end, tokens),
selection = TextRange(selection.start + tokens.length)
selection = TextRange(selection.start + tokens.length),
)
}
@ -93,7 +94,7 @@ fun TextFieldValue.addBracket(): TextFieldValue {
Token.Operator.plus,
Token.Operator.minus,
Token.Operator.power,
Token.Operator.leftBracket
Token.Operator.leftBracket,
)
if (text.tokenAhead(selection.start) in operators2) {
return addTokens(Token.Operator.leftBracket)
@ -122,7 +123,7 @@ fun TextFieldValue.deleteTokens(): TextFieldValue {
return this.copy(
text = newText,
selection = TextRange((newText.length - distanceFromEnd).coerceAtLeast(0))
selection = TextRange((newText.length - distanceFromEnd).coerceAtLeast(0)),
)
}

View File

@ -27,7 +27,7 @@ import androidx.annotation.RequiresApi
@RequiresApi(Build.VERSION_CODES.M)
internal class FloatingTextActionModeCallback(
private val callback: UnittoActionModeCallback
private val callback: UnittoActionModeCallback,
) : ActionMode.Callback2() {
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
return callback.onActionItemClicked(mode, item)
@ -48,14 +48,14 @@ internal class FloatingTextActionModeCallback(
override fun onGetContentRect(
mode: ActionMode?,
view: View?,
outRect: android.graphics.Rect?
outRect: android.graphics.Rect?,
) {
val rect = callback.rect
outRect?.set(
rect.left.toInt(),
rect.top.toInt(),
rect.right.toInt(),
rect.bottom.toInt()
rect.bottom.toInt(),
)
}
}

View File

@ -33,7 +33,7 @@ internal class UnittoActionModeCallback(
var onCopyRequested: (() -> Unit)? = null,
var onPasteRequested: (() -> Unit)? = null,
var onCutRequested: (() -> Unit)? = null,
var onSelectAllRequested: (() -> Unit)? = null
var onSelectAllRequested: (() -> Unit)? = null,
) {
fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
requireNotNull(menu)

View File

@ -23,7 +23,7 @@ import android.view.Menu
import android.view.MenuItem
internal class UnittoPrimaryTextActionModeCallback(
private val callback: UnittoActionModeCallback
private val callback: UnittoActionModeCallback,
) : ActionMode.Callback {
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
return callback.onActionItemClicked(mode, item)

View File

@ -29,7 +29,7 @@ class UnittoTextToolbar(
private val view: View,
private val copyCallback: () -> Unit,
private val pasteCallback: (() -> Unit)? = null,
private val cutCallback: (() -> Unit)? = null
private val cutCallback: (() -> Unit)? = null,
) : TextToolbar {
private var actionMode: ActionMode? = null
@ -42,7 +42,7 @@ class UnittoTextToolbar(
onCopyRequested: (() -> Unit)?,
onPasteRequested: (() -> Unit)?,
onCutRequested: (() -> Unit)?,
onSelectAllRequested: (() -> Unit)?
onSelectAllRequested: (() -> Unit)?,
) {
textActionModeCallback.rect = rect
textActionModeCallback.onCopyRequested = copyCallback
@ -66,17 +66,17 @@ class UnittoTextToolbar(
private fun startActionMode(
view: View,
textActionModeCallback: UnittoActionModeCallback
textActionModeCallback: UnittoActionModeCallback,
): ActionMode {
return if (Build.VERSION.SDK_INT >= 23) {
view.startActionMode(
FloatingTextActionModeCallback(textActionModeCallback),
ActionMode.TYPE_FLOATING
ActionMode.TYPE_FLOATING,
)
} else {
// Old devices use toolbar instead of a floating menu
view.startActionMode(
UnittoPrimaryTextActionModeCallback(textActionModeCallback)
UnittoPrimaryTextActionModeCallback(textActionModeCallback),
)
}
}

View File

@ -83,10 +83,11 @@ fun ZonedDateTime.formatTimeHours(
locale: Locale,
is24Hour: Boolean,
): String =
if (is24Hour)
if (is24Hour) {
format(UnittoDateTimeFormatter.time24Hours(locale))
else
} else {
format(UnittoDateTimeFormatter.time12Hours(locale))
}
/**
* @see UnittoDateTimeFormatter.timeMinutes
@ -132,7 +133,7 @@ fun ZonedDateTime.formatDateDayMonthYear(
* @see UnittoDateTimeFormatter.dateWeekDayMonthYear
*/
fun LocalDate.formatDateWeekDayMonthYear(
locale: Locale
locale: Locale,
): String =
format(UnittoDateTimeFormatter.dateWeekDayMonthYear(locale))
@ -155,7 +156,6 @@ fun LocalDate.formatDateWeekDayMonthYear(
fun ZonedDateTime.formatOffset(
currentTime: ZonedDateTime,
): String? {
val offsetFixed = ChronoUnit.SECONDS.between(currentTime, this)
var resultBuffer = ""

Some files were not shown because too many files have changed in this diff Show More