Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.thelightphone.sdk.InitialScreen
import com.thelightphone.sdk.SealedLightActivity
import com.thelightphone.sdk.SimpleLightScreen
import com.thelightphone.sdk.ui.LightFullscreenModal
import com.thelightphone.sdk.ui.LightScrollView
import com.thelightphone.sdk.ui.LightText
import com.thelightphone.sdk.ui.LightTextVariant
import com.thelightphone.sdk.ui.LightTheme
Expand Down Expand Up @@ -47,8 +48,9 @@ class UiDemoHomeScreen(sealedActivity: SealedLightActivity) :
modifier = Modifier.padding(bottom = 1f.gridUnitsAsDp()),
)

Column(
LightScrollView(
modifier = Modifier
.weight(1f)
.fillMaxWidth()
.padding(horizontal = 1f.gridUnitsAsDp()),
) {
Expand Down Expand Up @@ -113,6 +115,20 @@ class UiDemoHomeScreen(sealedActivity: SealedLightActivity) :
.lightClickable { LightThemeController.toggle() }
.padding(vertical = 0.75f.gridUnitsAsDp()),
)
LightText(
text = "PROGRESS BAR",
variant = LightTextVariant.Copy,
modifier = Modifier
.lightClickable { navigateTo(::UiDemoProgressBarScreen) }
.padding(vertical = 0.75f.gridUnitsAsDp()),
)
LightText(
text = "KEY EVENTS",
variant = LightTextVariant.Copy,
modifier = Modifier
.lightClickable { navigateTo(::UiDemoKeyEventsScreen) }
.padding(vertical = 0.75f.gridUnitsAsDp()),
)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.thelightphone.uidemo

import android.view.KeyEvent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.thelightphone.sdk.SealedLightActivity
import com.thelightphone.sdk.SimpleLightScreen
import com.thelightphone.sdk.ui.LightBarButton
import com.thelightphone.sdk.ui.LightIcons
import com.thelightphone.sdk.ui.LightScrollView
import com.thelightphone.sdk.ui.LightText
import com.thelightphone.sdk.ui.LightTextVariant
import com.thelightphone.sdk.ui.LightTheme
import com.thelightphone.sdk.ui.LightThemeController
import com.thelightphone.sdk.ui.LightTopBar
import com.thelightphone.sdk.ui.LightTopBarCenter
import com.thelightphone.sdk.ui.gridUnitsAsDp

private const val MAX_EVENTS = 20

class UiDemoKeyEventsScreen(sealedActivity: SealedLightActivity) :
SimpleLightScreen<Unit>(sealedActivity) {

// Newest-first, capped. Mutated from key dispatch (main thread), read by Content().
private val events = mutableStateListOf<String>()

private fun record(type: String, keyCode: Int, event: KeyEvent) {
events.add(0, "${KeyEvent.keyCodeToString(keyCode)} ($keyCode) $type " +
"action=${event.action} repeat=${event.repeatCount}")
if (events.size > MAX_EVENTS) events.removeRange(MAX_EVENTS, events.size)
}

// Return true to consume: keeps this screen self-contained (no server forwarding).
// BACK/HOME never arrive here — LightActivity short-circuits them before the screen.
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
record("DOWN", keyCode, event)
return true
}

override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
record("UP", keyCode, event)
return true
}

override fun onKeyMultiple(keyCode: Int, repeatCount: Int, event: KeyEvent): Boolean {
record("MULTIPLE", keyCode, event)
return true
}

@Composable
override fun Content() = ContentInner(events, onBack = { goBack() })
}

@Composable
private fun ContentInner(events: List<String>, onBack: () -> Unit) {
val themeColors by LightThemeController.colors.collectAsState()
LightTheme(colors = themeColors) {
Column(modifier = Modifier.fillMaxSize()) {
LightTopBar(
leftButton = LightBarButton.LightIcon(
icon = LightIcons.BACK,
onClick = onBack,
),
center = LightTopBarCenter.Text("Key Events"),
modifier = Modifier.padding(bottom = 1f.gridUnitsAsDp()),
)
if (events.isEmpty()) {
LightText(
text = "Press a hardware key…",
variant = LightTextVariant.Copy,
modifier = Modifier.padding(horizontal = 1f.gridUnitsAsDp()),
)
}
LightScrollView(
modifier = Modifier
.weight(1f)
.fillMaxWidth()
.padding(horizontal = 1f.gridUnitsAsDp()),
) {
events.forEach { line ->
LightText(
text = line,
variant = LightTextVariant.Superfine,
modifier = Modifier.padding(vertical = 0.5f.gridUnitsAsDp()),
)
}
}
}
}
}

@Preview(widthDp = 1080 / 3, heightDp = 1240 / 3, showBackground = true)
@Composable
fun UiDemoKeyEventsScreenPreview() {
ContentInner(
events = listOf(
"DOWN KEYCODE_VOLUME_UP (24) action=0 repeat=0",
"UP KEYCODE_VOLUME_UP (24) action=1 repeat=0",
),
onBack = {},
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.thelightphone.uidemo

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.thelightphone.sdk.SealedLightActivity
import com.thelightphone.sdk.SimpleLightScreen
import com.thelightphone.sdk.ui.LightBarButton
import com.thelightphone.sdk.ui.LightIcons
import com.thelightphone.sdk.ui.LightText
import com.thelightphone.sdk.ui.LightTextVariant
import com.thelightphone.sdk.ui.LightTheme
import com.thelightphone.sdk.ui.LightThemeController
import com.thelightphone.sdk.ui.LightTopBar
import com.thelightphone.sdk.ui.LightTopBarCenter
import com.thelightphone.sdk.ui.LightTouchableProgressBar
import com.thelightphone.sdk.ui.gridUnitsAsDp
import java.util.Locale

class UiDemoProgressBarScreen(sealedActivity: SealedLightActivity) :
SimpleLightScreen<Unit>(sealedActivity) {

@Composable
override fun Content() = ContentInner(onBack = { goBack() })
}

@Composable
private fun ContentInner(onBack: () -> Unit) {
val themeColors by LightThemeController.colors.collectAsState()
var progress by remember { mutableStateOf(0.5f) }
LightTheme(colors = themeColors) {
Column(modifier = Modifier.fillMaxSize()) {
LightTopBar(
leftButton = LightBarButton.LightIcon(
icon = LightIcons.BACK,
onClick = onBack,
),
center = LightTopBarCenter.Text("Progress Bar"),
modifier = Modifier.padding(bottom = 1f.gridUnitsAsDp()),
)
Column(
horizontalAlignment = CenterHorizontally,
modifier = Modifier
.fillMaxSize()
.padding(2f.gridUnitsAsDp())
) {
LightText("%.2f".format(Locale.ROOT, progress), variant = LightTextVariant.Copy)
LightTouchableProgressBar(themeColors, progress, onValueChange = { progress = it })
}
}
}
}

@Preview(widthDp = 1080 / 3, heightDp = 1240 / 3, showBackground = true)
@Composable
fun UiDemoProgressBarScreen() {
ContentInner(onBack = {})
}
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ 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.thelightphone.lp3keyboard:ui", version = "0.0.11"}
light-keyboard = { module = "com.thelightphone.lp3keyboard:ui", version = "0.0.16"}
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" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,44 +29,48 @@ object ManifestGenerator {
for (feature in features) {
appendLine(""" <uses-feature android:name="${xmlAttr(feature)}" android:required="false" />""")
}
appendLine(""" <application""")
appendLine(""" android:name="com.thelightphone.sdk.LightSdkApplication"""")
appendLine(""" android:label="${xmlAttr(metadata.label)}"""")
appendLine(""" android:supportsRtl="true"""")
appendLine(""" android:theme="@style/LightSdk.Theme.Splash">""")
appendLine(""" <meta-data""")
appendLine(""" android:name="com.thelightphone.sdk.LIGHT_SERVER_PACKAGE"""")
appendLine(""" android:value="${xmlAttr(metadata.serverPackage)}" />""")
appendLine(""" <activity""")
appendLine(""" android:name="com.thelightphone.sdk.LightActivity"""")
metadata.orientation?.let {
appendLine(""" android:screenOrientation="${xmlAttr(it)}"""")
}
appendLine(""" android:exported="true">""")
appendLine(""" <intent-filter>""")
appendLine(""" <action android:name="android.intent.action.MAIN" />""")
appendLine(""" <category android:name="android.intent.category.LAUNCHER" />""")
appendLine(""" </intent-filter>""")
appendLine(""" </activity>""")
appendLine(""" <receiver""")
appendLine(""" android:name="com.thelightphone.sdk.LightSdkReceiver"""")
appendLine(""" android:enabled="true"""")
appendLine(""" android:exported="true"""")
appendLine(""" android:permission="normal">""")
appendLine(""" <intent-filter>""")
appendLine(""" <action android:name="com.thelightphone.sdk.ACTION_SDK_MARKER" />""")
appendLine(""" </intent-filter>""")
appendLine(""" <meta-data""")
appendLine(""" android:name="com.thelightphone.sdk.SDK_VERSION"""")
appendLine(""" android:value="${'$'}{sdkVersion}" />""")
appendLine(""" </receiver>""")
appendLine(""" </application>""")
appendLine(""" <queries>""")
appendLine(""" <intent>""")
appendLine(""" <action android:name="com.thelightphone.sdk.ACTION_SDK_MARKER" />""")
appendLine(""" </intent>""")
appendLine(""" </queries>""")
appendLine("""</manifest>""")
val screenOrientation = metadata.orientation?.let {
"\n | android:screenOrientation=\"${xmlAttr(it)}\""
}.orEmpty()
appendLine(
"""
| <application
| android:name="com.thelightphone.sdk.LightSdkApplication"
| android:label="${xmlAttr(metadata.label)}"
| android:supportsRtl="true"
| android:theme="@style/LightSdk.Theme.Splash">
| <meta-data
| android:name="com.thelightphone.sdk.LIGHT_SERVER_PACKAGE"
| android:value="${xmlAttr(metadata.serverPackage)}" />
| <activity
| android:name="com.thelightphone.sdk.LightActivity"
| android:launchMode="singleTask"$screenOrientation
| android:exported="true">
| <intent-filter>
| <action android:name="android.intent.action.MAIN" />
| <category android:name="android.intent.category.LAUNCHER" />
| </intent-filter>
| </activity>
| <receiver
| android:name="com.thelightphone.sdk.LightSdkReceiver"
| android:enabled="true"
| android:exported="true"
| android:permission="normal">
| <intent-filter>
| <action android:name="com.thelightphone.sdk.ACTION_SDK_MARKER" />
| </intent-filter>
| <meta-data
| android:name="com.thelightphone.sdk.SDK_VERSION"
| android:value="${'$'}{sdkVersion}" />
| </receiver>
| </application>
| <queries>
| <intent>
| <action android:name="com.thelightphone.sdk.ACTION_SDK_MARKER" />
| </intent>
| </queries>
|</manifest>""".trimMargin()
)
}

private fun xmlAttr(value: String): String = buildString(value.length) {
Expand Down
Loading
Loading