Add gesture handler
This commit is contained in:
parent
3778e8405b
commit
7cd1269c33
@ -1,29 +1,49 @@
|
|||||||
package de.mm20.launcher2.ui.gestures
|
package de.mm20.launcher2.ui.gestures
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.compose.runtime.staticCompositionLocalOf
|
import androidx.compose.runtime.staticCompositionLocalOf
|
||||||
import androidx.compose.ui.geometry.Offset
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
|
||||||
class GestureManager {
|
class GestureDetector {
|
||||||
private var dragStart: Offset? = null
|
private var dragStart: Offset? = null
|
||||||
private var currentDrag : Offset? = null
|
private var currentDrag : Offset? = null
|
||||||
|
|
||||||
fun reportDoubleTap(position: Offset) {
|
var gestureListener: OnGestureListener? = null
|
||||||
|
|
||||||
|
fun dispatchDoubleTap(position: Offset) {
|
||||||
|
gestureListener?.onDoubleTap(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportLongPress(position: Offset) {
|
fun dispatchLongPress(position: Offset) {
|
||||||
|
gestureListener?.onLongPress(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportDrag(offset: Offset) {
|
private var hasDragEnded = false
|
||||||
currentDrag = (currentDrag ?: Offset.Zero) + offset
|
fun dispatchDrag(offset: Offset) {
|
||||||
|
if (hasDragEnded) return
|
||||||
|
val totalDrag = currentDrag?.plus(offset) ?: offset
|
||||||
|
currentDrag = totalDrag
|
||||||
|
if (gestureListener?.onDrag(totalDrag) == true) hasDragEnded = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportDragEnd() {
|
fun dispatchDragEnd() {
|
||||||
dragStart = null
|
dragStart = null
|
||||||
currentDrag = null
|
currentDrag = null
|
||||||
|
hasDragEnded = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface OnGestureListener {
|
||||||
|
fun onDoubleTap(position: Offset) {}
|
||||||
|
fun onLongPress(position: Offset) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the drag gesture has been handled.
|
||||||
|
* The gesture detector will no longer track the drag gesture in this case.
|
||||||
|
*/
|
||||||
|
fun onDrag(offset: Offset): Boolean = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val LocalGestureManager = staticCompositionLocalOf<GestureManager> {
|
val LocalGestureDetector = staticCompositionLocalOf<GestureDetector> {
|
||||||
GestureManager()
|
GestureDetector()
|
||||||
}
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package de.mm20.launcher2.ui.gestures
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun GestureHandler(
|
||||||
|
detector: GestureDetector,
|
||||||
|
onLongPress: (Offset) -> Unit = {},
|
||||||
|
onDoubleTap: (Offset) -> Unit = {},
|
||||||
|
onDrag: (Offset) -> Boolean = { false },
|
||||||
|
) {
|
||||||
|
DisposableEffect(detector) {
|
||||||
|
detector.gestureListener = object : GestureDetector.OnGestureListener {
|
||||||
|
override fun onLongPress(position: Offset) {
|
||||||
|
onLongPress(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDoubleTap(position: Offset) {
|
||||||
|
onDoubleTap(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDrag(offset: Offset): Boolean {
|
||||||
|
return onDrag(offset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onDispose {
|
||||||
|
detector.gestureListener = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,13 +7,11 @@ import androidx.compose.animation.core.animateDpAsState
|
|||||||
import androidx.compose.animation.slideIn
|
import androidx.compose.animation.slideIn
|
||||||
import androidx.compose.animation.slideOut
|
import androidx.compose.animation.slideOut
|
||||||
import androidx.compose.foundation.LocalOverscrollConfiguration
|
import androidx.compose.foundation.LocalOverscrollConfiguration
|
||||||
import androidx.compose.foundation.gestures.Orientation
|
|
||||||
import androidx.compose.foundation.gestures.detectTapGestures
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
import androidx.compose.foundation.layout.asPaddingValues
|
import androidx.compose.foundation.layout.asPaddingValues
|
||||||
import androidx.compose.foundation.layout.calculateStartPadding
|
import androidx.compose.foundation.layout.calculateStartPadding
|
||||||
@ -33,11 +31,8 @@ import androidx.compose.foundation.pager.HorizontalPager
|
|||||||
import androidx.compose.foundation.pager.rememberPagerState
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.FractionalThreshold
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.rounded.Done
|
import androidx.compose.material.icons.rounded.Done
|
||||||
import androidx.compose.material.rememberSwipeableState
|
|
||||||
import androidx.compose.material.swipeable
|
|
||||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
import androidx.compose.material3.CenterAlignedTopAppBar
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
@ -52,10 +47,8 @@ import androidx.compose.runtime.livedata.observeAsState
|
|||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
|
||||||
import androidx.compose.ui.geometry.Offset
|
import androidx.compose.ui.geometry.Offset
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
@ -68,7 +61,6 @@ import androidx.compose.ui.platform.LocalLayoutDirection
|
|||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.IntOffset
|
import androidx.compose.ui.unit.IntOffset
|
||||||
import androidx.compose.ui.unit.LayoutDirection
|
|
||||||
import androidx.compose.ui.unit.Velocity
|
import androidx.compose.ui.unit.Velocity
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
@ -77,9 +69,8 @@ import de.mm20.launcher2.preferences.Settings.SearchBarSettings.SearchBarColors
|
|||||||
import de.mm20.launcher2.preferences.Settings.SearchBarSettings.SearchBarStyle
|
import de.mm20.launcher2.preferences.Settings.SearchBarSettings.SearchBarStyle
|
||||||
import de.mm20.launcher2.ui.R
|
import de.mm20.launcher2.ui.R
|
||||||
import de.mm20.launcher2.ui.component.SearchBarLevel
|
import de.mm20.launcher2.ui.component.SearchBarLevel
|
||||||
import de.mm20.launcher2.ui.gestures.LocalGestureManager
|
import de.mm20.launcher2.ui.gestures.LocalGestureDetector
|
||||||
import de.mm20.launcher2.ui.ktx.animateTo
|
import de.mm20.launcher2.ui.ktx.animateTo
|
||||||
import de.mm20.launcher2.ui.ktx.toPixels
|
|
||||||
import de.mm20.launcher2.ui.launcher.helper.WallpaperBlur
|
import de.mm20.launcher2.ui.launcher.helper.WallpaperBlur
|
||||||
import de.mm20.launcher2.ui.launcher.search.SearchColumn
|
import de.mm20.launcher2.ui.launcher.search.SearchColumn
|
||||||
import de.mm20.launcher2.ui.launcher.search.SearchVM
|
import de.mm20.launcher2.ui.launcher.search.SearchVM
|
||||||
@ -87,10 +78,8 @@ import de.mm20.launcher2.ui.launcher.searchbar.LauncherSearchBar
|
|||||||
import de.mm20.launcher2.ui.launcher.widgets.WidgetColumn
|
import de.mm20.launcher2.ui.launcher.widgets.WidgetColumn
|
||||||
import de.mm20.launcher2.ui.launcher.widgets.clock.ClockWidget
|
import de.mm20.launcher2.ui.launcher.widgets.clock.ClockWidget
|
||||||
import de.mm20.launcher2.ui.locals.LocalPreferDarkContentOverWallpaper
|
import de.mm20.launcher2.ui.locals.LocalPreferDarkContentOverWallpaper
|
||||||
import de.mm20.launcher2.ui.utils.rememberNotificationShadeController
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PagerScaffold(
|
fun PagerScaffold(
|
||||||
@ -252,7 +241,7 @@ fun PagerScaffold(
|
|||||||
|
|
||||||
val keyboardController = LocalSoftwareKeyboardController.current
|
val keyboardController = LocalSoftwareKeyboardController.current
|
||||||
|
|
||||||
val gestureManager = LocalGestureManager.current
|
val gestureManager = LocalGestureDetector.current
|
||||||
|
|
||||||
val searchBarOffset = remember { mutableStateOf(0f) }
|
val searchBarOffset = remember { mutableStateOf(0f) }
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
@ -265,14 +254,14 @@ fun PagerScaffold(
|
|||||||
available: Offset,
|
available: Offset,
|
||||||
source: NestedScrollSource
|
source: NestedScrollSource
|
||||||
): Offset {
|
): Offset {
|
||||||
if (source == NestedScrollSource.Drag) gestureManager.reportDrag(available)
|
if (source == NestedScrollSource.Drag) gestureManager.dispatchDrag(available)
|
||||||
val deltaSearchBarOffset = consumed.y * if (isSearchOpen && reverseSearchResults) 1 else -1
|
val deltaSearchBarOffset = consumed.y * if (isSearchOpen && reverseSearchResults) 1 else -1
|
||||||
searchBarOffset.value = (searchBarOffset.value + deltaSearchBarOffset).coerceIn(0f, maxSearchBarOffset)
|
searchBarOffset.value = (searchBarOffset.value + deltaSearchBarOffset).coerceIn(0f, maxSearchBarOffset)
|
||||||
return super.onPostScroll(consumed, available, source)
|
return super.onPostScroll(consumed, available, source)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun onPreFling(available: Velocity): Velocity {
|
override suspend fun onPreFling(available: Velocity): Velocity {
|
||||||
gestureManager.reportDragEnd()
|
gestureManager.dispatchDragEnd()
|
||||||
return super.onPreFling(available)
|
return super.onPreFling(available)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -350,10 +339,10 @@ fun PagerScaffold(
|
|||||||
.pointerInput(Unit) {
|
.pointerInput(Unit) {
|
||||||
detectTapGestures(
|
detectTapGestures(
|
||||||
onDoubleTap = {
|
onDoubleTap = {
|
||||||
gestureManager.reportDoubleTap(it)
|
gestureManager.dispatchDoubleTap(it)
|
||||||
},
|
},
|
||||||
onLongPress = {
|
onLongPress = {
|
||||||
gestureManager.reportLongPress(it)
|
gestureManager.dispatchLongPress(it)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -453,7 +442,6 @@ fun PagerScaffold(
|
|||||||
|
|
||||||
val searchBarLevel by remember {
|
val searchBarLevel by remember {
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
Log.d("MM20", pagerState.currentPageOffsetFraction.toString())
|
|
||||||
when {
|
when {
|
||||||
pagerState.currentPageOffsetFraction != 0f -> SearchBarLevel.Raised
|
pagerState.currentPageOffsetFraction != 0f -> SearchBarLevel.Raised
|
||||||
!isSearchOpen && isWidgetsScrollZero && fillClockHeight -> SearchBarLevel.Resting
|
!isSearchOpen && isWidgetsScrollZero && fillClockHeight -> SearchBarLevel.Resting
|
||||||
|
|||||||
@ -7,11 +7,8 @@ import androidx.compose.animation.core.animateFloatAsState
|
|||||||
import androidx.compose.animation.slideIn
|
import androidx.compose.animation.slideIn
|
||||||
import androidx.compose.animation.slideOut
|
import androidx.compose.animation.slideOut
|
||||||
import androidx.compose.foundation.LocalOverscrollConfiguration
|
import androidx.compose.foundation.LocalOverscrollConfiguration
|
||||||
import androidx.compose.foundation.gestures.Orientation
|
|
||||||
import androidx.compose.foundation.gestures.detectHorizontalDragGestures
|
import androidx.compose.foundation.gestures.detectHorizontalDragGestures
|
||||||
import androidx.compose.foundation.gestures.detectTapGestures
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
import androidx.compose.foundation.gestures.scrollable
|
|
||||||
import androidx.compose.foundation.horizontalScroll
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@ -69,7 +66,7 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
|||||||
import de.mm20.launcher2.preferences.Settings
|
import de.mm20.launcher2.preferences.Settings
|
||||||
import de.mm20.launcher2.ui.R
|
import de.mm20.launcher2.ui.R
|
||||||
import de.mm20.launcher2.ui.component.SearchBarLevel
|
import de.mm20.launcher2.ui.component.SearchBarLevel
|
||||||
import de.mm20.launcher2.ui.gestures.LocalGestureManager
|
import de.mm20.launcher2.ui.gestures.LocalGestureDetector
|
||||||
import de.mm20.launcher2.ui.ktx.animateTo
|
import de.mm20.launcher2.ui.ktx.animateTo
|
||||||
import de.mm20.launcher2.ui.launcher.helper.WallpaperBlur
|
import de.mm20.launcher2.ui.launcher.helper.WallpaperBlur
|
||||||
import de.mm20.launcher2.ui.launcher.search.SearchColumn
|
import de.mm20.launcher2.ui.launcher.search.SearchColumn
|
||||||
@ -248,7 +245,7 @@ fun PullDownScaffold(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val keyboardController = LocalSoftwareKeyboardController.current
|
val keyboardController = LocalSoftwareKeyboardController.current
|
||||||
val gestureManager = LocalGestureManager.current
|
val gestureManager = LocalGestureDetector.current
|
||||||
|
|
||||||
val nestedScrollConnection = remember {
|
val nestedScrollConnection = remember {
|
||||||
object : NestedScrollConnection {
|
object : NestedScrollConnection {
|
||||||
@ -297,7 +294,7 @@ fun PullDownScaffold(
|
|||||||
if (offsetY.value > toggleSearchThreshold || offsetY.value < -toggleSearchThreshold) {
|
if (offsetY.value > toggleSearchThreshold || offsetY.value < -toggleSearchThreshold) {
|
||||||
viewModel.toggleSearch()
|
viewModel.toggleSearch()
|
||||||
}
|
}
|
||||||
gestureManager.reportDragEnd()
|
gestureManager.dispatchDragEnd()
|
||||||
if (offsetY.value != 0f) {
|
if (offsetY.value != 0f) {
|
||||||
offsetY.animateTo(0f)
|
offsetY.animateTo(0f)
|
||||||
return available
|
return available
|
||||||
@ -313,10 +310,10 @@ fun PullDownScaffold(
|
|||||||
.pointerInput(Unit) {
|
.pointerInput(Unit) {
|
||||||
detectHorizontalDragGestures(
|
detectHorizontalDragGestures(
|
||||||
onDragEnd = {
|
onDragEnd = {
|
||||||
gestureManager.reportDragEnd()
|
gestureManager.dispatchDragEnd()
|
||||||
},
|
},
|
||||||
onHorizontalDrag = { _, dragAmount ->
|
onHorizontalDrag = { _, dragAmount ->
|
||||||
gestureManager.reportDrag(Offset(dragAmount, 0f))
|
gestureManager.dispatchDrag(Offset(dragAmount, 0f))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -399,10 +396,10 @@ fun PullDownScaffold(
|
|||||||
.pointerInput(Unit) {
|
.pointerInput(Unit) {
|
||||||
detectTapGestures(
|
detectTapGestures(
|
||||||
onDoubleTap = {
|
onDoubleTap = {
|
||||||
gestureManager.reportDoubleTap(it)
|
gestureManager.dispatchDoubleTap(it)
|
||||||
},
|
},
|
||||||
onLongPress = {
|
onLongPress = {
|
||||||
gestureManager.reportLongPress(it)
|
gestureManager.dispatchLongPress(it)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import android.app.WallpaperManager
|
|||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
@ -29,6 +30,7 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.graphics.TransformOrigin
|
import androidx.compose.ui.graphics.TransformOrigin
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.WindowInsetsControllerCompat
|
import androidx.core.view.WindowInsetsControllerCompat
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
@ -41,10 +43,13 @@ import de.mm20.launcher2.ui.base.BaseActivity
|
|||||||
import de.mm20.launcher2.ui.base.ProvideCurrentTime
|
import de.mm20.launcher2.ui.base.ProvideCurrentTime
|
||||||
import de.mm20.launcher2.ui.base.ProvideSettings
|
import de.mm20.launcher2.ui.base.ProvideSettings
|
||||||
import de.mm20.launcher2.ui.component.NavBarEffects
|
import de.mm20.launcher2.ui.component.NavBarEffects
|
||||||
|
import de.mm20.launcher2.ui.gestures.GestureDetector
|
||||||
|
import de.mm20.launcher2.ui.gestures.GestureHandler
|
||||||
|
import de.mm20.launcher2.ui.gestures.LocalGestureDetector
|
||||||
import de.mm20.launcher2.ui.ktx.animateTo
|
import de.mm20.launcher2.ui.ktx.animateTo
|
||||||
|
import de.mm20.launcher2.ui.ktx.toPixels
|
||||||
import de.mm20.launcher2.ui.launcher.sheets.CustomizeSearchableSheet
|
import de.mm20.launcher2.ui.launcher.sheets.CustomizeSearchableSheet
|
||||||
import de.mm20.launcher2.ui.launcher.sheets.EditFavoritesSheet
|
import de.mm20.launcher2.ui.launcher.sheets.EditFavoritesSheet
|
||||||
import de.mm20.launcher2.ui.launcher.sheets.HiddenItemsSheet
|
|
||||||
import de.mm20.launcher2.ui.launcher.sheets.LauncherBottomSheetManager
|
import de.mm20.launcher2.ui.launcher.sheets.LauncherBottomSheetManager
|
||||||
import de.mm20.launcher2.ui.launcher.sheets.LocalBottomSheetManager
|
import de.mm20.launcher2.ui.launcher.sheets.LocalBottomSheetManager
|
||||||
import de.mm20.launcher2.ui.launcher.transitions.HomeTransition
|
import de.mm20.launcher2.ui.launcher.transitions.HomeTransition
|
||||||
@ -56,6 +61,7 @@ import de.mm20.launcher2.ui.locals.LocalWallpaperColors
|
|||||||
import de.mm20.launcher2.ui.locals.LocalWindowSize
|
import de.mm20.launcher2.ui.locals.LocalWindowSize
|
||||||
import de.mm20.launcher2.ui.theme.LauncherTheme
|
import de.mm20.launcher2.ui.theme.LauncherTheme
|
||||||
import de.mm20.launcher2.ui.theme.wallpaperColorsAsState
|
import de.mm20.launcher2.ui.theme.wallpaperColorsAsState
|
||||||
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
|
|
||||||
@ -81,6 +87,7 @@ abstract class SharedLauncherActivity(
|
|||||||
viewModel.setSystemInDarkMode(resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES)
|
viewModel.setSystemInDarkMode(resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES)
|
||||||
|
|
||||||
val bottomSheetManager = LauncherBottomSheetManager()
|
val bottomSheetManager = LauncherBottomSheetManager()
|
||||||
|
val gestureDetector = GestureDetector()
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
val snackbarHostState = remember { SnackbarHostState() }
|
||||||
@ -93,15 +100,20 @@ abstract class SharedLauncherActivity(
|
|||||||
LocalWallpaperColors provides wallpaperColors,
|
LocalWallpaperColors provides wallpaperColors,
|
||||||
LocalPreferDarkContentOverWallpaper provides (!dimBackground && wallpaperColors.supportsDarkText),
|
LocalPreferDarkContentOverWallpaper provides (!dimBackground && wallpaperColors.supportsDarkText),
|
||||||
LocalBottomSheetManager provides bottomSheetManager,
|
LocalBottomSheetManager provides bottomSheetManager,
|
||||||
|
LocalGestureDetector provides gestureDetector,
|
||||||
) {
|
) {
|
||||||
LauncherTheme {
|
LauncherTheme {
|
||||||
ProvideCurrentTime {
|
ProvideCurrentTime {
|
||||||
ProvideSettings {
|
ProvideSettings {
|
||||||
val statusBarColor by viewModel.statusBarColor.observeAsState(SystemBarColors.Auto)
|
val statusBarColor by viewModel.statusBarColor.observeAsState(
|
||||||
|
SystemBarColors.Auto
|
||||||
|
)
|
||||||
val navBarColor by viewModel.navBarColor.observeAsState(SystemBarColors.Auto)
|
val navBarColor by viewModel.navBarColor.observeAsState(SystemBarColors.Auto)
|
||||||
|
|
||||||
val lightStatus = !dimBackground && (statusBarColor == SystemBarColors.Dark || statusBarColor == SystemBarColors.Auto && wallpaperColors.supportsDarkText)
|
val lightStatus =
|
||||||
val lightNav = !dimBackground && (navBarColor == SystemBarColors.Dark || navBarColor == SystemBarColors.Auto && wallpaperColors.supportsDarkText)
|
!dimBackground && (statusBarColor == SystemBarColors.Dark || statusBarColor == SystemBarColors.Auto && wallpaperColors.supportsDarkText)
|
||||||
|
val lightNav =
|
||||||
|
!dimBackground && (navBarColor == SystemBarColors.Dark || navBarColor == SystemBarColors.Auto && wallpaperColors.supportsDarkText)
|
||||||
|
|
||||||
val hideStatus by viewModel.hideStatusBar.observeAsState(false)
|
val hideStatus by viewModel.hideStatusBar.observeAsState(false)
|
||||||
val hideNav by viewModel.hideNavBar.observeAsState(false)
|
val hideNav by viewModel.hideNavBar.observeAsState(false)
|
||||||
@ -207,7 +219,8 @@ abstract class SharedLauncherActivity(
|
|||||||
enterTransition?.let {
|
enterTransition?.let {
|
||||||
val dX = it.startBounds.center.x - it.targetBounds.center.x
|
val dX = it.startBounds.center.x - it.targetBounds.center.x
|
||||||
val dY = it.startBounds.center.y - it.targetBounds.center.y
|
val dY = it.startBounds.center.y - it.targetBounds.center.y
|
||||||
val s = (it.startBounds.minDimension / it.targetBounds.minDimension - 1f) * 0.5f
|
val s =
|
||||||
|
(it.startBounds.minDimension / it.targetBounds.minDimension - 1f) * 0.5f
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.TopStart)
|
.align(Alignment.TopStart)
|
||||||
@ -220,17 +233,60 @@ abstract class SharedLauncherActivity(
|
|||||||
scaleX = 1f + s * (1 - p)
|
scaleX = 1f + s * (1 - p)
|
||||||
scaleY = 1f + s * (1 - p)
|
scaleY = 1f + s * (1 - p)
|
||||||
}) {
|
}) {
|
||||||
it.icon?.invoke(Offset(dX, dY)) { enterTransitionProgress.value }
|
it.icon?.invoke(
|
||||||
|
Offset(
|
||||||
|
dX,
|
||||||
|
dY
|
||||||
|
)
|
||||||
|
) { enterTransitionProgress.value }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bottomSheetManager.customizeSearchableSheetShown.value?.let {
|
bottomSheetManager.customizeSearchableSheetShown.value?.let {
|
||||||
CustomizeSearchableSheet(searchable = it, onDismiss = { bottomSheetManager.dismissCustomizeSearchableModal() })
|
CustomizeSearchableSheet(
|
||||||
|
searchable = it,
|
||||||
|
onDismiss = { bottomSheetManager.dismissCustomizeSearchableModal() })
|
||||||
}
|
}
|
||||||
if (bottomSheetManager.editFavoritesSheetShown.value) {
|
if (bottomSheetManager.editFavoritesSheetShown.value) {
|
||||||
EditFavoritesSheet(onDismiss = { bottomSheetManager.dismissEditFavoritesSheet() })
|
EditFavoritesSheet(onDismiss = { bottomSheetManager.dismissEditFavoritesSheet() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val swipeThreshold = 150.dp.toPixels()
|
||||||
|
GestureHandler(
|
||||||
|
detector = gestureDetector,
|
||||||
|
onDoubleTap = {
|
||||||
|
Log.d("MM20", "Double tap")
|
||||||
|
},
|
||||||
|
onLongPress = {
|
||||||
|
Log.d("MM20", "Long press")
|
||||||
|
},
|
||||||
|
onDrag = {
|
||||||
|
return@GestureHandler when {
|
||||||
|
it.x > swipeThreshold && it.x.absoluteValue > it.y.absoluteValue * 2f -> {
|
||||||
|
Log.d("MM20", "Swipe right")
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
it.x < -swipeThreshold && it.x.absoluteValue > it.y.absoluteValue * 2f -> {
|
||||||
|
Log.d("MM20", "Swipe left")
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
it.y > swipeThreshold && it.y.absoluteValue > it.x.absoluteValue * 2f -> {
|
||||||
|
Log.d("MM20", "Swipe down")
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
it.y < -swipeThreshold && it.y.absoluteValue > it.x.absoluteValue * 2f -> {
|
||||||
|
Log.d("MM20", "Swipe up")
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user