Skip to content

Commit

Permalink
update project setup api
Browse files Browse the repository at this point in the history
  • Loading branch information
Tlaster committed Oct 16, 2023
1 parent 19a7521 commit 4287c5b
Show file tree
Hide file tree
Showing 21 changed files with 319 additions and 158 deletions.
13 changes: 1 addition & 12 deletions precompose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,7 @@ group = "moe.tlaster"
version = rootProject.extra.get("precomposeVersion") as String

kotlin {
targetHierarchy.default {
common {
group("nonAndroidJvm") {
withMacosArm64()
withMacosX64()
withIosX64()
withIosArm64()
withIosSimulatorArm64()
withJs()
}
}
}
targetHierarchy.default()
macosArm64()
macosX64()
iosX64()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.LocalSaveableStateRegistry
import androidx.compose.ui.Modifier
import androidx.lifecycle.DefaultLifecycleObserver
import moe.tlaster.precompose.lifecycle.Lifecycle
import moe.tlaster.precompose.lifecycle.LocalLifecycleOwner
Expand All @@ -20,7 +19,6 @@ import moe.tlaster.precompose.ui.LocalBackDispatcherOwner

@Composable
actual fun PreComposeApp(
modifier: Modifier,
content: @Composable () -> Unit,
) {
val viewModel = androidx.lifecycle.viewmodel.compose.viewModel<PreComposeViewModel>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ import androidx.savedstate.findViewTreeSavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
import moe.tlaster.precompose.PreComposeApp

@Deprecated(
message = "Use PreComposeApp instead",
replaceWith = ReplaceWith("PreComposeApp(content)"),
)
typealias PreComposeActivity = ComponentActivity

@Deprecated(
message = "Use PreComposeApp instead",
replaceWith = ReplaceWith("PreComposeApp(content)"),
)
fun ComponentActivity.setContent(
parent: CompositionContext? = null,
content: @Composable () -> Unit,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package moe.tlaster.precompose

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

@Composable
expect fun PreComposeApp(
modifier: Modifier = Modifier,
content: @Composable () -> Unit = {},
)
Original file line number Diff line number Diff line change
@@ -1,11 +1,35 @@
package moe.tlaster.precompose

import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember
import androidx.compose.ui.uikit.ComposeUIViewControllerConfiguration
import androidx.compose.ui.window.ComposeUIViewController
import kotlinx.cinterop.BetaInteropApi
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.ObjCAction
import moe.tlaster.precompose.lifecycle.Lifecycle
import moe.tlaster.precompose.lifecycle.LifecycleOwner
import moe.tlaster.precompose.lifecycle.LifecycleRegistry
import moe.tlaster.precompose.lifecycle.LocalLifecycleOwner
import moe.tlaster.precompose.stateholder.LocalStateHolder
import moe.tlaster.precompose.stateholder.StateHolder
import moe.tlaster.precompose.ui.BackDispatcher
import moe.tlaster.precompose.ui.BackDispatcherOwner
import moe.tlaster.precompose.ui.LocalBackDispatcherOwner
import platform.Foundation.NSNotification
import platform.Foundation.NSNotificationCenter
import platform.Foundation.NSSelectorFromString
import platform.UIKit.UIApplicationDidEnterBackgroundNotification
import platform.UIKit.UIApplicationWillEnterForegroundNotification
import platform.UIKit.UIApplicationWillTerminateNotification
import platform.UIKit.UIViewController

@Suppress("FunctionName")
@Deprecated(
message = "Use PreComposeApp instead",
replaceWith = ReplaceWith("PreComposeApp(content)"),
)
fun PreComposeApplication(
configure: ComposeUIViewControllerConfiguration.() -> Unit = {},
content: @Composable () -> Unit,
Expand All @@ -16,3 +40,79 @@ fun PreComposeApplication(
}
}
}

@Composable
actual fun PreComposeApp(
content: @Composable () -> Unit,
) {
ProvidePreComposeCompositionLocals {
content.invoke()
}
}

@Composable
fun ProvidePreComposeCompositionLocals(
holder: PreComposeWindowHolder = remember {
PreComposeWindowHolder()
},
content: @Composable () -> Unit,
) {
CompositionLocalProvider(
LocalLifecycleOwner provides holder,
LocalStateHolder provides holder.stateHolder,
LocalBackDispatcherOwner provides holder,
) {
content.invoke()
}
}

@OptIn(ExperimentalForeignApi::class)
class PreComposeWindowHolder : LifecycleOwner, BackDispatcherOwner {
override val lifecycle by lazy {
LifecycleRegistry()
}
val stateHolder by lazy {
StateHolder()
}
override val backDispatcher by lazy {
BackDispatcher()
}
init {
NSNotificationCenter.defaultCenter().addObserver(
this,
selector = NSSelectorFromString("appMovedToForeground:"),
name = UIApplicationWillEnterForegroundNotification,
`object` = null,
)
NSNotificationCenter.defaultCenter().addObserver(
this,
selector = NSSelectorFromString("appMovedToBackground:"),
name = UIApplicationDidEnterBackgroundNotification,
`object` = null,
)
NSNotificationCenter.defaultCenter().addObserver(
this,
selector = NSSelectorFromString("appWillTerminate:"),
name = UIApplicationWillTerminateNotification,
`object` = null,
)
}

@OptIn(BetaInteropApi::class)
@ObjCAction
fun appMovedToForeground(notification: NSNotification) {
lifecycle.currentState = Lifecycle.State.Active
}

@OptIn(BetaInteropApi::class)
@ObjCAction
fun appMovedToBackground(notification: NSNotification) {
lifecycle.currentState = Lifecycle.State.InActive
}

@OptIn(BetaInteropApi::class)
@ObjCAction
fun appWillTerminate(notification: NSNotification) {
lifecycle.currentState = Lifecycle.State.Destroyed
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
package moe.tlaster.precompose

import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.window.CanvasBasedWindow
import moe.tlaster.precompose.lifecycle.LifecycleOwner
import moe.tlaster.precompose.lifecycle.LifecycleRegistry
import moe.tlaster.precompose.lifecycle.LocalLifecycleOwner
import moe.tlaster.precompose.stateholder.LocalStateHolder
import moe.tlaster.precompose.stateholder.StateHolder
import moe.tlaster.precompose.ui.BackDispatcher
import moe.tlaster.precompose.ui.BackDispatcherOwner
import moe.tlaster.precompose.ui.LocalBackDispatcherOwner

/**
* Creates a new [CanvasBasedWindow] with the given [title] and [content].
Expand All @@ -28,3 +38,40 @@ fun preComposeWindow(
},
)
}

@Composable
actual fun PreComposeApp(
content: @Composable () -> Unit,
) {
ProvidePreComposeCompositionLocals {
content.invoke()
}
}

@Composable
fun ProvidePreComposeCompositionLocals(
holder: PreComposeWindowHolder = remember {
PreComposeWindowHolder()
},
content: @Composable () -> Unit,
) {
CompositionLocalProvider(
LocalLifecycleOwner provides holder,
LocalStateHolder provides holder.stateHolder,
LocalBackDispatcherOwner provides holder,
) {
content.invoke()
}
}

class PreComposeWindowHolder : LifecycleOwner, BackDispatcherOwner {
override val lifecycle by lazy {
LifecycleRegistry()
}
val stateHolder by lazy {
StateHolder()
}
override val backDispatcher by lazy {
BackDispatcher()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.window.FrameWindowScope
Expand All @@ -23,6 +22,10 @@ import moe.tlaster.precompose.ui.LocalBackDispatcherOwner
import java.awt.event.WindowAdapter
import java.awt.event.WindowEvent

@Deprecated(
message = "Use PreComposeApp instead",
replaceWith = ReplaceWith("PreComposeApp(content)"),
)
@Composable
fun PreComposeWindow(
onCloseRequest: () -> Unit,
Expand Down Expand Up @@ -65,7 +68,6 @@ fun PreComposeWindow(
@Suppress("INVISIBLE_MEMBER")
@Composable
actual fun PreComposeApp(
modifier: Modifier,
content: @Composable () -> Unit,
) {
val holder = remember {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ internal class ComposeWindow(
hideTitleBar: Boolean = false,
initialTitle: String,
private val onCloseRequest: () -> Unit = {},
private val onMinimizeRequest: () -> Unit = {},
private val onDeminiaturizeRequest: () -> Unit = {},
) : NSObject(), NSWindowDelegateProtocol {

private val density by lazy {
Density(
density = nsWindow.backingScaleFactor.toFloat(),
fontScale = 1f,
)
}
private val macosTextInputService = MacosTextInputService()
Expand Down Expand Up @@ -184,6 +185,18 @@ internal class ComposeWindow(
onCloseRequest.invoke()
}

@OptIn(BetaInteropApi::class)
@ObjCAction
override fun windowWillMiniaturize(notification: NSNotification) {
onMinimizeRequest.invoke()
}

@OptIn(BetaInteropApi::class)
@ObjCAction
override fun windowDidDeminiaturize(notification: NSNotification) {
onDeminiaturizeRequest.invoke()
}

private fun updateLayerSize() {
val (w, h) = nsWindow.contentView!!.frame.useContents {
size.width to size.height
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
package moe.tlaster.precompose

import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember
import moe.tlaster.precompose.lifecycle.LifecycleOwner
import moe.tlaster.precompose.lifecycle.LifecycleRegistry
import moe.tlaster.precompose.lifecycle.LocalLifecycleOwner
import moe.tlaster.precompose.stateholder.LocalStateHolder
import moe.tlaster.precompose.stateholder.StateHolder
import moe.tlaster.precompose.ui.BackDispatcher
import moe.tlaster.precompose.ui.BackDispatcherOwner
import moe.tlaster.precompose.ui.LocalBackDispatcherOwner

fun PreComposeWindow(
title: String,
hideTitleBar: Boolean = false,
onCloseRequest: () -> Unit = {},
onMinimizeRequest: () -> Unit = {},
onDeminiaturizeRequest: () -> Unit = {},
content: @Composable () -> Unit,
) {
// Ugly workaround until Native macOS support window resize and hide title bar.
ComposeWindow(
hideTitleBar = hideTitleBar,
initialTitle = title,
onCloseRequest = onCloseRequest,
onMinimizeRequest = onMinimizeRequest,
onDeminiaturizeRequest = onDeminiaturizeRequest,
).apply {
setContent {
PreComposeApp {
Expand All @@ -21,3 +35,40 @@ fun PreComposeWindow(
}
}
}

@Composable
actual fun PreComposeApp(
content: @Composable () -> Unit,
) {
ProvidePreComposeCompositionLocals {
content.invoke()
}
}

@Composable
fun ProvidePreComposeCompositionLocals(
holder: PreComposeWindowHolder = remember {
PreComposeWindowHolder()
},
content: @Composable () -> Unit,
) {
CompositionLocalProvider(
LocalLifecycleOwner provides holder,
LocalStateHolder provides holder.stateHolder,
LocalBackDispatcherOwner provides holder,
) {
content.invoke()
}
}

class PreComposeWindowHolder : LifecycleOwner, BackDispatcherOwner {
override val lifecycle by lazy {
LifecycleRegistry()
}
val stateHolder by lazy {
StateHolder()
}
override val backDispatcher by lazy {
BackDispatcher()
}
}
Loading

0 comments on commit 4287c5b

Please sign in to comment.