Animate closing windows into their icons
This commit is contained in:
parent
9f93f0c750
commit
6908f94417
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 }
|
||||
@ -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)
|
||||
}
|
||||
@ -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
|
||||
)
|
||||
Loading…
x
Reference in New Issue
Block a user