Skip to content
This repository has been archived by the owner on Aug 7, 2024. It is now read-only.

Commit

Permalink
Merge pull request #221 from SuhasDissa/main
Browse files Browse the repository at this point in the history
Add floating button to pause recording + better annotation tool switching
  • Loading branch information
SuhasDissa authored Oct 30, 2023
2 parents b3bdad5 + e5fa079 commit c81336a
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,35 @@ import android.os.Build
import android.util.Log
import android.view.Gravity
import android.view.WindowManager
import androidx.activity.ComponentActivity
import androidx.annotation.RequiresApi
import androidx.compose.ui.platform.ComposeView
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.setViewTreeLifecycleOwner
import androidx.lifecycle.setViewTreeViewModelStoreOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
import com.bnyro.recorder.ui.theme.RecordYouTheme
import com.bnyro.recorder.util.CustomLifecycleOwner

@RequiresApi(Build.VERSION_CODES.O)
class CanvasOverlay(context: Context) {
private var windowManager = context.getSystemService(WINDOW_SERVICE) as WindowManager
private var canvasView = ComposeView(context).apply {
val activity = context as ComponentActivity
setViewTreeLifecycleOwner(activity)
setViewTreeViewModelStoreOwner(activity)
setViewTreeSavedStateRegistryOwner(activity)
setContent {
RecordYouTheme() {
MainCanvas()
}
}
}
private var toolbarView = ComposeView(context).apply {
val activity = context as ComponentActivity
setViewTreeLifecycleOwner(activity)
setViewTreeViewModelStoreOwner(activity)
setViewTreeSavedStateRegistryOwner(activity)
setContent {
RecordYouTheme {
ToolbarView(hideCanvas = { hide ->
Expand All @@ -45,20 +50,6 @@ class CanvasOverlay(context: Context) {
}

init {
val lifecycleOwner = CustomLifecycleOwner()
val viewModelStoreOwner = object : ViewModelStoreOwner {
override val viewModelStore: ViewModelStore = ViewModelStore()
}
lifecycleOwner.performRestore(null)
lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
canvasView.setViewTreeLifecycleOwner(lifecycleOwner)
canvasView.setViewTreeViewModelStoreOwner(viewModelStoreOwner)
canvasView.setViewTreeSavedStateRegistryOwner(lifecycleOwner)

toolbarView.setViewTreeLifecycleOwner(lifecycleOwner)
toolbarView.setViewTreeViewModelStoreOwner(viewModelStoreOwner)
toolbarView.setViewTreeSavedStateRegistryOwner(lifecycleOwner)

hideCanvas()
}

Expand All @@ -68,7 +59,7 @@ class CanvasOverlay(context: Context) {
size,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSPARENT,
PixelFormat.TRANSPARENT
)
}

Expand Down
80 changes: 51 additions & 29 deletions app/src/main/java/com/bnyro/recorder/canvas_overlay/ToolbarView.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.bnyro.recorder.canvas_overlay

import android.content.Intent
import android.os.Build
import androidx.compose.foundation.layout.Row
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Draw
import androidx.compose.material.icons.filled.Stop
import androidx.compose.material.icons.rounded.Clear
import androidx.compose.material.icons.rounded.Draw
import androidx.compose.material.icons.rounded.Pause
import androidx.compose.material.icons.rounded.PlayArrow
import androidx.compose.material.icons.rounded.Stop
import androidx.compose.material3.Card
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
Expand All @@ -14,56 +16,76 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.viewmodel.compose.viewModel
import com.bnyro.recorder.R
import com.bnyro.recorder.services.RecorderService
import com.bnyro.recorder.enums.RecorderState
import com.bnyro.recorder.ui.models.RecorderModel

@Composable
fun ToolbarView(
hideCanvas: (Boolean) -> Unit,
canvasViewModel: CanvasViewModel = viewModel()
canvasViewModel: CanvasViewModel = viewModel(),
recorderModel: RecorderModel = viewModel()
) {
var currentDrawMode by remember { mutableStateOf(DrawMode.Pen) }
var currentDrawMode by remember { mutableStateOf(DrawMode.Eraser) }
Card() {
Row {
IconButton(
onClick = {
currentDrawMode = DrawMode.Pen
currentDrawMode = if (currentDrawMode == DrawMode.Eraser) {
hideCanvas(false)
DrawMode.Pen
} else {
DrawMode.Eraser
}
canvasViewModel.currentPath.drawMode = currentDrawMode
hideCanvas(false)
}
) {
Icon(imageVector = Icons.Default.Draw, contentDescription = "Draw Mode")
}
IconButton(
onClick = {
currentDrawMode = DrawMode.Eraser
canvasViewModel.currentPath.drawMode = currentDrawMode
if (currentDrawMode == DrawMode.Eraser) {
Icon(
imageVector = Icons.Rounded.Draw,
contentDescription = stringResource(R.string.draw_mode)
)
} else {
Icon(
painter = painterResource(id = R.drawable.ic_eraser_black_24dp),
contentDescription = stringResource(R.string.erase_mode)
)
}
) {
Icon(
painter = painterResource(id = R.drawable.ic_eraser_black_24dp),
contentDescription = "Erase Mode"
)
}
IconButton(onClick = {
hideCanvas(true)
canvasViewModel.paths.clear()
}) {
Icon(Icons.Default.Close, "Show/Hide Canvas")
Icon(Icons.Rounded.Clear, "Show/Hide Canvas")
}
val context = LocalContext.current
IconButton(onClick = {
val intent = Intent().apply {
action = RecorderService.RECORDER_INTENT_ACTION
putExtra(RecorderService.ACTION_EXTRA_KEY, RecorderService.STOP_ACTION)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
IconButton(onClick = {
if (recorderModel.recorderState == RecorderState.PAUSED) {
recorderModel.resumeRecording()
} else {
recorderModel.pauseRecording()
}
}) {
if (recorderModel.recorderState == RecorderState.PAUSED) {
Icon(
Icons.Rounded.PlayArrow,
contentDescription = stringResource(id = R.string.resume)
)
} else {
Icon(
Icons.Rounded.Pause,
contentDescription = stringResource(id = R.string.pause)
)
}
}
context.sendBroadcast(intent)
}
IconButton(onClick = {
recorderModel.stopRecording()
}) {
Icon(Icons.Default.Stop, stringResource(id = R.string.stop))
Icon(Icons.Rounded.Stop, stringResource(id = R.string.stop))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.bnyro.recorder.ui.components

import android.text.format.DateUtils
import androidx.activity.ComponentActivity
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
Expand All @@ -15,6 +16,7 @@ import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.drawscope.translate
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.rememberTextMeasurer
Expand All @@ -27,7 +29,7 @@ import com.bnyro.recorder.util.Preferences
fun AudioVisualizer(
modifier: Modifier = Modifier
) {
val viewModel: RecorderModel = viewModel()
val viewModel: RecorderModel = viewModel(LocalContext.current as ComponentActivity)
val showTimestamps = remember {
Preferences.prefs.getBoolean(
Preferences.showVisualizerTimestamps,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.Context
import android.media.projection.MediaProjectionManager
import android.os.Build
import android.text.format.DateUtils
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.background
Expand Down Expand Up @@ -52,7 +53,7 @@ fun RecorderController(
recordScreenMode: Boolean,
initialRecorder: RecorderType
) {
val recorderModel: RecorderModel = viewModel()
val recorderModel: RecorderModel = viewModel(LocalContext.current as ComponentActivity)
val context = LocalContext.current
val mProjectionManager =
context.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package com.bnyro.recorder.ui.components

import androidx.activity.ComponentActivity
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewmodel.compose.viewModel
import com.bnyro.recorder.R
import com.bnyro.recorder.ui.common.BlobIconBox
import com.bnyro.recorder.ui.models.RecorderModel

@Composable
fun RecorderPreview(recordScreenMode: Boolean) {
val recorderModel: RecorderModel = viewModel()
val recorderModel: RecorderModel = viewModel(LocalContext.current as ComponentActivity)
if (recordScreenMode) {
BlobIconBox(
icon = R.drawable.ic_screen_record
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.bnyro.recorder.ui.screens

import android.view.SoundEffectConstants
import androidx.activity.ComponentActivity
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Column
Expand All @@ -23,6 +24,7 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.viewmodel.compose.viewModel
Expand All @@ -39,7 +41,7 @@ import kotlinx.coroutines.launch
fun HomeScreen(
initialRecorder: RecorderType,
onNavigate: (Destination) -> Unit,
recorderModel: RecorderModel = viewModel()
recorderModel: RecorderModel = viewModel(LocalContext.current as ComponentActivity)
) {
val pagerState = rememberPagerState { 2 }
val scope = rememberCoroutineScope()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.bnyro.recorder.ui.screens

import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewmodel.compose.viewModel
import com.bnyro.recorder.enums.RecorderState
import com.bnyro.recorder.enums.RecorderType
Expand All @@ -19,7 +21,7 @@ fun RecorderView(
initialRecorder: RecorderType,
recordScreenMode: Boolean
) {
val recorderModel: RecorderModel = viewModel()
val recorderModel: RecorderModel = viewModel(LocalContext.current as ComponentActivity)

LaunchedEffect(recorderModel.recorderState) {
// update the UI when the recorder gets destroyed by the notification
Expand All @@ -41,4 +43,4 @@ fun RecorderView(
}
)
}
}
}
31 changes: 0 additions & 31 deletions app/src/main/java/com/bnyro/recorder/util/CustomLifecycleOwner.kt

This file was deleted.

2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,6 @@
<string name="trimming">Trimming…</string>
<string name="trim_successful">Trim Successful</string>
<string name="cant_access_selected_folder">Can\'t access selected folder!</string>
<string name="draw_mode">Draw Mode</string>
<string name="erase_mode">Erase Mode</string>
</resources>

0 comments on commit c81336a

Please sign in to comment.