diff --git a/examples/ui-demo/src/main/kotlin/com/thelightphone/uidemo/UiDemoTextInputEditorScreen.kt b/examples/ui-demo/src/main/kotlin/com/thelightphone/uidemo/UiDemoTextInputEditorScreen.kt index dce3702b..76eb01e3 100644 --- a/examples/ui-demo/src/main/kotlin/com/thelightphone/uidemo/UiDemoTextInputEditorScreen.kt +++ b/examples/ui-demo/src/main/kotlin/com/thelightphone/uidemo/UiDemoTextInputEditorScreen.kt @@ -1,11 +1,17 @@ package com.thelightphone.uidemo import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.text.input.rememberTextFieldState +import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.thelightphone.lp3Keyboard.ui.KeyboardOptions +import com.thelightphone.lp3Keyboard.ui.viewmodel.defaultEmojis import com.thelightphone.sdk.SealedLightActivity import com.thelightphone.sdk.SimpleLightScreen import com.thelightphone.sdk.rememberKeyboardOptions @@ -13,6 +19,8 @@ import com.thelightphone.sdk.ui.LightTextInputEditor import com.thelightphone.sdk.ui.LightTheme import com.thelightphone.sdk.ui.LightThemeController import com.thelightphone.sdk.ui.LightThemeTokens +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow data class EditorRequest( val title: String, @@ -27,19 +35,48 @@ class UiDemoTextInputEditorScreen( @Composable override fun Content() { - val textState = rememberTextFieldState(editorRequest.initialValue) - val themeColors by LightThemeController.colors.collectAsState() val keyboardOptionsFlow = rememberKeyboardOptions() - LightTheme(colors = themeColors) { - LightTextInputEditor( - title = editorRequest.title, - state = textState, - keyboardOptionsFlow = keyboardOptionsFlow, - onSubmit = { result -> goBack(result.toString()) }, - onBack = { goBack(null) }, - modifier = Modifier.background(LightThemeTokens.colors.background), - initialCaps = editorRequest.initialCaps, - ) + ContentInner(keyboardOptionsFlow, editorRequest, this::goBack) + } +} + +@Composable +private fun ContentInner( + keyboardOptionsFlow: StateFlow, + editorRequest: EditorRequest, + goBack: (String?) -> Unit +) { + val textState = rememberTextFieldState(editorRequest.initialValue) + val themeColors by LightThemeController.colors.collectAsState() + LightTheme(colors = themeColors) { + LightTextInputEditor( + title = editorRequest.title, + state = textState, + keyboardOptionsFlow = keyboardOptionsFlow, + onSubmit = { result -> goBack(result.toString()) }, + onBack = { goBack(null) }, + modifier = Modifier.background(LightThemeTokens.colors.background), + initialCaps = editorRequest.initialCaps, + ) + } +} + +@Preview(widthDp = 1080 / 3, heightDp = 1240 / 3, showBackground = true) +@Composable +fun TextEditorPreview() { + val editorRequest = EditorRequest("Text Input", "Hello") + val keyboardOptionsFlow = MutableStateFlow( + KeyboardOptions( + defaultEmojis, + displayReturn = true, + displayVoice = true, + enableKeyAnimation = true, + swipeEnabled = true + ) + ) + Surface { + Box(Modifier.fillMaxSize()) { + ContentInner(keyboardOptionsFlow, editorRequest) { } } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4de00cef..44c093a4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -42,7 +42,9 @@ ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" } ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } ktor-serialization-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } -light-keyboard = { module = "com.github.lightphone:light-keyboard", version = "v0.0.16"} +light-keyboard = { module = "com.github.lightphone:light-keyboard", version = "v0.0.18"} +# for local dev +# light-keyboard = { module = "com.thelightphone.lp3keyboard:ui", version = "0.0.17-dirty"} androidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "camerax" } androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camerax" } androidx-camera-lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref = "camerax" } diff --git a/sdk/ui/src/main/kotlin/com/thelightphone/sdk/ui/LightBottomBar.kt b/sdk/ui/src/main/kotlin/com/thelightphone/sdk/ui/LightBottomBar.kt index 7e54702a..e0bf907e 100644 --- a/sdk/ui/src/main/kotlin/com/thelightphone/sdk/ui/LightBottomBar.kt +++ b/sdk/ui/src/main/kotlin/com/thelightphone/sdk/ui/LightBottomBar.kt @@ -1,9 +1,11 @@ package com.thelightphone.sdk.ui +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -11,6 +13,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp private const val BOTTOMBAR_HEIGHT_UNITS = 4f private const val HORIZONTAL_PADDING_MULTI_UNITS = 2f @@ -28,6 +31,7 @@ private val BOTTOMBAR_TEXT_VARIANT = LightTextVariant.Button fun LightBottomBar( items: List, modifier: Modifier = Modifier, + topPadding: Dp = TOP_MARGIN_UNITS.gridUnitsAsDp() ) { require(items.size <= 5) { "LightBottomBar supports at most 5 items" } @@ -45,7 +49,7 @@ fun LightBottomBar( Row( modifier = modifier .fillMaxWidth() - .padding(top = TOP_MARGIN_UNITS.gridUnitsAsDp()) + .padding(top = topPadding) .height(barHeight) .padding(horizontal = horizontalPadding), verticalAlignment = Alignment.CenterVertically, @@ -137,9 +141,11 @@ private fun LightBottomBarItemView(item: LightBottomBarItem?) { private fun isMixedIconTextIconLayout(items: List): Boolean { if (items.size != 3) return false - val firstIsIconOrEmpty = items[0] == null || items[0] is LightBarButton.LightIcon || items[0] is LightBarButton.Icon + val firstIsIconOrEmpty = + items[0] == null || items[0] is LightBarButton.LightIcon || items[0] is LightBarButton.Icon val centerIsText = items[1] is LightBarButton.Text - val lastIsIconOrEmpty = items[2] == null || items[2] is LightBarButton.LightIcon || items[2] is LightBarButton.Icon + val lastIsIconOrEmpty = + items[2] == null || items[2] is LightBarButton.LightIcon || items[2] is LightBarButton.Icon return firstIsIconOrEmpty && centerIsText && lastIsIconOrEmpty } @@ -148,13 +154,19 @@ private fun isMixedIconTextIconLayout(items: List): Boolean @Composable private fun PreviewLightBottomBarIconsDark() { LightTheme(colors = LightThemeColors.Dark) { - LightBottomBar( - items = listOf( - LightBarButton.LightIcon(icon = LightIcons.DIALPAD, onClick = {}), - LightBarButton.LightIcon(icon = LightIcons.SEARCH, onClick = {}), - LightBarButton.LightIcon(icon = LightIcons.CONTACTS, onClick = {}), - ), - ) + Box( + modifier = Modifier + .fillMaxSize() + .background(LightThemeTokens.colors.background) + ) { + LightBottomBar( + items = listOf( + LightBarButton.LightIcon(icon = LightIcons.DIALPAD, onClick = {}), + LightBarButton.LightIcon(icon = LightIcons.SEARCH, onClick = {}), + LightBarButton.LightIcon(icon = LightIcons.CONTACTS, onClick = {}), + ), + ) + } } } diff --git a/sdk/ui/src/main/kotlin/com/thelightphone/sdk/ui/LightTextInputEditor.kt b/sdk/ui/src/main/kotlin/com/thelightphone/sdk/ui/LightTextInputEditor.kt index 69703eaa..9fa3448d 100644 --- a/sdk/ui/src/main/kotlin/com/thelightphone/sdk/ui/LightTextInputEditor.kt +++ b/sdk/ui/src/main/kotlin/com/thelightphone/sdk/ui/LightTextInputEditor.kt @@ -17,6 +17,7 @@ import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity @@ -193,22 +194,27 @@ fun LightTextInputEditor( } } - LightEmbeddedLp3Keyboard(viewModel = viewModel) - - LightBottomBar( - items = listOf( - when (submitIcon) { - null -> LightBarButton.Text( - text = submitLabel, - onClick = { onSubmit(state.text) }, - ) - else -> LightBarButton.LightIcon( - icon = submitIcon, - onClick = { onSubmit(state.text) }, - contentDescription = submitLabel, - ) - }, - ), + LightEmbeddedLp3Keyboard( + viewModel = viewModel, + additionalBottomHeight = 5f.gridUnitsAsDp(), + bottomBar = { + LightBottomBar( + topPadding = 0.dp, + items = listOf( + when (submitIcon) { + null -> LightBarButton.Text( + text = submitLabel, + onClick = { onSubmit(state.text) }, + ) + else -> LightBarButton.LightIcon( + icon = submitIcon, + onClick = { onSubmit(state.text) }, + contentDescription = submitLabel, + ) + }, + ), + ) + } ) } } diff --git a/sdk/ui/src/main/kotlin/com/thelightphone/sdk/ui/keyboard/LightEmbeddedLp3Keyboard.kt b/sdk/ui/src/main/kotlin/com/thelightphone/sdk/ui/keyboard/LightEmbeddedLp3Keyboard.kt index 085d7d8b..dbeb44d6 100644 --- a/sdk/ui/src/main/kotlin/com/thelightphone/sdk/ui/keyboard/LightEmbeddedLp3Keyboard.kt +++ b/sdk/ui/src/main/kotlin/com/thelightphone/sdk/ui/keyboard/LightEmbeddedLp3Keyboard.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.thelightphone.lp3Keyboard.ui.DarkKeyboardColors import com.thelightphone.lp3Keyboard.ui.LightKeyboardColors @@ -17,9 +18,16 @@ import com.thelightphone.lp3Keyboard.ui.Lp3KeyboardWrapper import com.thelightphone.lp3Keyboard.ui.viewmodel.Lp3KeyboardViewModel import com.thelightphone.sdk.ui.LightThemeColors import com.thelightphone.sdk.ui.LightThemeTokens +import kotlin.Int @Composable -fun LightEmbeddedLp3Keyboard(viewModel: Lp3KeyboardViewModel<*>) { +fun LightEmbeddedLp3Keyboard( + viewModel: Lp3KeyboardViewModel<*>, + additionalBottomHeight: Dp = 0.dp, + bottomBar: (@Composable () -> Unit)? = null, + onOverlayDismissed: (() -> Unit)? = null, + overlay: (@Composable () -> Unit)? = null, +) { val layout by viewModel.layoutFlow.collectAsState() val keyboardOptions by viewModel.keyboardOptionsFlow.collectAsState() val layoutOptions by viewModel.layoutOptionsFlow.collectAsState() @@ -42,7 +50,11 @@ fun LightEmbeddedLp3Keyboard(viewModel: Lp3KeyboardViewModel<*>) { keyboardOptions = keyboardOptions, layoutOptions = layoutOptions, callback = viewModel, - swipeCallback = null + swipeCallback = null, + additionalBottomHeight = additionalBottomHeight, + bottomBar = bottomBar, + onOverlayDismissed = onOverlayDismissed, + overlay = overlay ) } }