Skip to content

Commit

Permalink
Add Scrollbar Indicator and Progress Indicator for the Timer
Browse files Browse the repository at this point in the history
  • Loading branch information
NiroDeveloper committed May 17, 2024
1 parent d6e7146 commit cc998cb
Show file tree
Hide file tree
Showing 12 changed files with 160 additions and 74 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ dependencies {
implementation(libs.core.splashscreen)
implementation(libs.wear.tooling.preview)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.horologist.compose.layout)
implementation(libs.fragment)
implementation(libs.wear)

androidTestImplementation(platform(libs.compose.bom))
androidTestImplementation(libs.ui.test.junit4)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import dev.niro.cameraremote.R
import dev.niro.cameraremote.bluetooth.helper.BluetoothPermission
import dev.niro.cameraremote.bluetooth.helper.sendKeyboardPress
import dev.niro.cameraremote.interfaces.IConnectionStateCallback
import dev.niro.cameraremote.interfaces.IUserInterfaceCallback
import dev.niro.cameraremote.interfaces.IUserInterfaceBluetoothCallback
import dev.niro.cameraremote.ui.activities.BluetoothPermissionActivity

object BluetoothController {

var uiCallback: IUserInterfaceCallback? = null
var uiCallback: IUserInterfaceBluetoothCallback? = null

private var bluetoothCallback: BluetoothServiceCallback? = null

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package dev.niro.cameraremote.interfaces

interface IAmbientModeState {

fun isAmbientModeActive(): Boolean

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package dev.niro.cameraremote.interfaces

interface IUserInterfaceBluetoothCallback : IConnectionStateCallback

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package dev.niro.cameraremote.interfaces

interface IUserInterfaceTimerCallback : IAmbientModeState {

fun shouldChangeProgressIndicator(progress: Float)

}
25 changes: 22 additions & 3 deletions app/src/main/java/dev/niro/cameraremote/ui/UserInputController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package dev.niro.cameraremote.ui

import android.content.Context
import dev.niro.cameraremote.bluetooth.BluetoothController
import dev.niro.cameraremote.interfaces.IUserInterfaceTimerCallback
import dev.niro.cameraremote.utils.Vibrator
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand All @@ -20,6 +21,8 @@ object UserInputController {

private var triggerCoroutine: Job? = null

var uiCallback: IUserInterfaceTimerCallback? = null

fun clickTrigger(context: Context) {
triggerCoroutine?.cancel()

Expand All @@ -34,11 +37,27 @@ object UserInputController {
triggerCoroutine = CoroutineScope(Dispatchers.Default).launch {
var firstPicture = true
do {
for (waitCounter in 1..timerDelay) {
if (firstPicture || waitCounter > 1) {
val configuredTimerDelay = timerDelay

for (waitCounter in 0..<configuredTimerDelay) {
if (firstPicture || waitCounter > 0) {
Vibrator.tick(context)
}
delay(1000L)

val tickFPS = if (uiCallback?.isAmbientModeActive() == true) { 1 } else { 40 }

for (subTick in 1..tickFPS) {
delay(1000L / tickFPS)

val subTickProgress = subTick / tickFPS.toFloat()
val progress = (waitCounter + subTickProgress) / configuredTimerDelay

uiCallback?.shouldChangeProgressIndicator(progress)
}
}

if (configuredTimerDelay == 0) {
uiCallback?.shouldChangeProgressIndicator(1f)
}

Vibrator.shoot(context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
import androidx.wear.compose.material.Button
import androidx.wear.compose.material.Icon
import androidx.wear.compose.material.PositionIndicator
import androidx.wear.compose.material.Text
import androidx.wear.tooling.preview.devices.WearDevices
import com.google.android.horologist.annotations.ExperimentalHorologistApi
import com.google.android.horologist.compose.layout.ScalingLazyColumn
import com.google.android.horologist.compose.layout.ScalingLazyColumnState
import dev.niro.cameraremote.R
import dev.niro.cameraremote.bluetooth.helper.BluetoothPermission

Expand Down Expand Up @@ -55,16 +55,19 @@ class BluetoothPermissionActivity : ComponentActivity() {
}


@OptIn(ExperimentalHorologistApi::class)
@Preview(device = WearDevices.RECT, showSystemUi = true)
@Preview(device = WearDevices.SQUARE, showSystemUi = true)
@Preview(device = WearDevices.SMALL_ROUND, showSystemUi = true)
@Preview(device = WearDevices.LARGE_ROUND, showSystemUi = true)
@Composable
fun BluetoothPermissionLayout(onOk: (() -> Unit)? = null) {
val scalingState = rememberScalingLazyListState(0, 100)

PositionIndicator(scalingLazyListState = scalingState)

ScalingLazyColumn(
modifier = Modifier.fillMaxSize(),
columnState = ScalingLazyColumnState(initialScrollPosition = ScalingLazyColumnState.ScrollPosition(0, 100))
state = scalingState
) {
item {
Icon(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
import androidx.wear.compose.material.Button
import androidx.wear.compose.material.Icon
import androidx.wear.compose.material.PositionIndicator
import androidx.wear.compose.material.Text
import androidx.wear.tooling.preview.devices.WearDevices
import com.google.android.horologist.annotations.ExperimentalHorologistApi
import com.google.android.horologist.compose.layout.ScalingLazyColumn
import com.google.android.horologist.compose.layout.ScalingLazyColumnState
import dev.niro.cameraremote.R

class ErrorActivity : ComponentActivity() {
Expand All @@ -39,20 +39,22 @@ class ErrorActivity : ComponentActivity() {
}

}

@OptIn(ExperimentalHorologistApi::class)
@Preview(device = WearDevices.RECT, showSystemUi = true)
@Preview(device = WearDevices.SQUARE, showSystemUi = true)
@Preview(device = WearDevices.SMALL_ROUND, showSystemUi = true)
@Preview(device = WearDevices.LARGE_ROUND, showSystemUi = true)
@Composable
fun ErrorLayout(
message: String = "This is a very long error message that describes what happened.",
message: String = "This is a very long error message that describes what happened.\n\nHere is some more text to read.",
onOk: (() -> Unit)? = null
) {
val scalingState = rememberScalingLazyListState(0, 100)

PositionIndicator(scalingLazyListState = scalingState)

ScalingLazyColumn(
modifier = Modifier.fillMaxSize(),
columnState = ScalingLazyColumnState(initialScrollPosition = ScalingLazyColumnState.ScrollPosition(0, 100))
state = scalingState
) {
item {
Icon(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,28 @@ import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import com.google.android.horologist.compose.ambient.AmbientAware
import androidx.wear.ambient.AmbientLifecycleObserver
import dev.niro.cameraremote.bluetooth.BluetoothController
import dev.niro.cameraremote.bluetooth.helper.BluetoothPermission
import dev.niro.cameraremote.interfaces.IAmbientModeState
import dev.niro.cameraremote.ui.pages.RemoteLayout
import dev.niro.cameraremote.ui.pages.RemotePage

class MainActivity : ComponentActivity() {
class MainActivity : ComponentActivity(), AmbientLifecycleObserver.AmbientLifecycleCallback, IAmbientModeState {

private val ambientObserver = AmbientLifecycleObserver(this, this)

private var isInAmbientMode = false

override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen()

super.onCreate(savedInstanceState)
lifecycle.addObserver(ambientObserver)

BluetoothController.init(this)
RemotePage.registerCallbacks(this)
RemotePage.updateButtons()

// Must be created at activity startup, otherwise the app will crash.
val permissionLauncher = BluetoothPermission.buildPermissionLauncher(this) { permissionGranted ->
Expand All @@ -33,15 +42,26 @@ class MainActivity : ComponentActivity() {
}

setContent {
AmbientAware {
RemoteLayout(permissionLauncher)
}
RemoteLayout(permissionLauncher)
}
}

override fun onDestroy() {
super.onDestroy()
lifecycle.removeObserver(ambientObserver)

BluetoothController.destroy(this)
}

override fun onEnterAmbient(ambientDetails: AmbientLifecycleObserver.AmbientDetails) {
isInAmbientMode = true
}

override fun onExitAmbient() {
isInAmbientMode = false
}

override fun isAmbientModeActive(): Boolean {
return isInAmbientMode
}
}
Loading

0 comments on commit cc998cb

Please sign in to comment.