Animate closing windows into their icons

This commit is contained in:
MM20 2022-05-12 20:27:01 +02:00
parent 9f93f0c750
commit 6908f94417
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
8 changed files with 106 additions and 8 deletions

View File

@ -36,7 +36,7 @@ class GestureNavContract(
* Sends the position information to the receiver
*/
@TargetApi(Build.VERSION_CODES.R)
fun sendEndPosition(position: RectF?, surfaceControl: SurfaceControl?) {
fun sendEndPosition(position: RectF? = null, surfaceControl: SurfaceControl? = null) {
val result = Bundle()
result.putParcelable(EXTRA_ICON_POSITION, position)
result.putParcelable(EXTRA_ICON_SURFACE, surfaceControl)

View File

@ -2,6 +2,7 @@ package de.mm20.launcher2.ui.launcher
import android.content.Intent
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.activity.viewModels
@ -16,6 +17,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsControllerCompat
@ -35,6 +37,7 @@ import de.mm20.launcher2.ui.launcher.modals.EditFavoritesView
import de.mm20.launcher2.ui.launcher.modals.HiddenItemsSheet
import de.mm20.launcher2.ui.launcher.transitions.HomeTransitionManager
import de.mm20.launcher2.ui.launcher.transitions.LocalHomeTransitionManager
import de.mm20.launcher2.ui.locals.LocalWindowSize
import de.mm20.launcher2.ui.theme.LauncherTheme
import org.koin.android.ext.android.inject
@ -48,13 +51,18 @@ class LauncherActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val windowSize = Resources.getSystem().displayMetrics.let {
Size(it.widthPixels.toFloat(), it.heightPixels.toFloat())
}
WindowCompat.setDecorFitsSystemWindows(window, false)
viewModel.setDarkMode(resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES)
setContent {
CompositionLocalProvider(
LocalHomeTransitionManager provides homeTransitionManager
LocalHomeTransitionManager provides homeTransitionManager,
LocalWindowSize provides windowSize
) {
LauncherTheme {
ProvideSettings {

View File

@ -1,10 +1,10 @@
package de.mm20.launcher2.ui.launcher.search.common
package de.mm20.launcher2.ui.launcher.search.common.grid
import android.content.ComponentName
import androidx.activity.compose.BackHandler
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@ -29,19 +29,19 @@ import de.mm20.launcher2.ui.ktx.toDp
import de.mm20.launcher2.ui.ktx.toPixels
import de.mm20.launcher2.ui.launcher.search.apps.AppItemGridPopup
import de.mm20.launcher2.ui.launcher.search.calendar.CalendarItemGridPopup
import de.mm20.launcher2.ui.launcher.search.common.grid.GridItemVM
import de.mm20.launcher2.ui.launcher.search.contacts.ContactItemGridPopup
import de.mm20.launcher2.ui.launcher.search.files.FileItemGridPopup
import de.mm20.launcher2.ui.launcher.search.shortcut.ShortcutItemGridPopup
import de.mm20.launcher2.ui.launcher.search.website.WebsiteItemGridPopup
import de.mm20.launcher2.ui.launcher.search.wikipedia.WikipediaItemGridPopup
import de.mm20.launcher2.ui.launcher.transitions.HandleHomeTransition
import de.mm20.launcher2.ui.launcher.transitions.HomeTransitionParams
import de.mm20.launcher2.ui.locals.LocalGridIconSize
import de.mm20.launcher2.ui.locals.LocalWindowPosition
import de.mm20.launcher2.ui.locals.LocalWindowSize
import kotlinx.coroutines.delay
import kotlin.math.pow
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun GridItem(modifier: Modifier = Modifier, item: Searchable, showLabels: Boolean = true) {
val viewModel = remember(item.key) { GridItemVM(item) }
@ -58,6 +58,22 @@ fun GridItem(modifier: Modifier = Modifier, item: Searchable, showLabels: Boolea
val launchOnPress =
item is File || item is Application || item is AppShortcut || item is Website || item is Wikipedia
val windowSize = LocalWindowSize.current
if (item is Application) {
HandleHomeTransition {
val cn = ComponentName(item.`package`, item.activity)
if (
it.componentName == cn &&
bounds.right > 0f && bounds.left < windowSize.width &&
bounds.bottom > 0f && bounds.top < windowSize.height
) {
return@HandleHomeTransition HomeTransitionParams(bounds)
}
return@HandleHomeTransition null
}
}
ShapedLauncherIcon(
modifier = Modifier
.onGloballyPositioned {

View File

@ -6,7 +6,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.ui.launcher.search.common.GridItem
import de.mm20.launcher2.ui.layout.BottomReversed
import de.mm20.launcher2.ui.locals.LocalGridColumns
import kotlin.math.ceil

View File

@ -0,0 +1,22 @@
package de.mm20.launcher2.ui.launcher.transitions
import android.content.ComponentName
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import com.android.launcher3.GestureNavContract
fun interface HomeTransitionHandler {
fun handle(gestureNavContract: GestureNavContract): HomeTransitionParams?
}
@Composable
fun HandleHomeTransition(handler: HomeTransitionHandler) {
val transitionManager = LocalHomeTransitionManager.current
DisposableEffect(null) {
transitionManager?.registerHandler(handler)
onDispose {
transitionManager?.unregisterHandler(handler)
}
}
}

View File

@ -0,0 +1,36 @@
package de.mm20.launcher2.ui.launcher.transitions
import androidx.compose.runtime.Composable
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.toAndroidRectF
import com.android.launcher3.GestureNavContract
class HomeTransitionManager {
private val handlers = mutableSetOf<HomeTransitionHandler>()
fun resolve(gestureNavContract: GestureNavContract) {
for (handler in handlers) {
val result = handler.handle(gestureNavContract)
if (result != null) {
gestureNavContract.sendEndPosition(result.targetBounds.toAndroidRectF())
break
}
}
}
private fun dispatch(params: HomeTransitionParams) {
}
fun registerHandler(handler: HomeTransitionHandler) {
handlers.add(handler)
}
fun unregisterHandler(handler: HomeTransitionHandler) {
handlers.remove(handler)
}
}
val LocalHomeTransitionManager = compositionLocalOf<HomeTransitionManager?> { null }

View File

@ -0,0 +1,8 @@
package de.mm20.launcher2.ui.launcher.transitions
import androidx.compose.runtime.Composable
import androidx.compose.ui.geometry.Rect
fun interface HomeTransitionOffer {
fun accept(targetBounds: Rect, icon: @Composable () -> Unit)
}

View File

@ -0,0 +1,9 @@
package de.mm20.launcher2.ui.launcher.transitions
import androidx.compose.runtime.Composable
import androidx.compose.ui.geometry.Rect
data class HomeTransitionParams(
val targetBounds: Rect,
val icon: (@Composable () -> Unit)? = null
)