Skip to content

Commit

Permalink
Fix safe area and add image from native resources
Browse files Browse the repository at this point in the history
  • Loading branch information
cl3m committed Nov 18, 2022
1 parent e4bb7cb commit 3118055
Show file tree
Hide file tree
Showing 11 changed files with 173 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.rouge41.kmm.compose.androidApp

import android.graphics.Color
import android.os.Bundle
import com.rouge41.kmm.compose.Android
import com.rouge41.kmm.compose.RootView
import moe.tlaster.precompose.lifecycle.PreComposeActivity
import moe.tlaster.precompose.lifecycle.setContent
Expand All @@ -14,6 +15,7 @@ class MainActivity : PreComposeActivity() {
window.decorView.setBackgroundColor(Color.WHITE)
window.statusBarColor = Color.parseColor("#cc7000")

Android.context = this
setContent {
RootView()
}
Expand Down
10 changes: 7 additions & 3 deletions iosApp/iosApp/AvoidDispose.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

import UIKit
import test

// ComposeWindow is disposed on viewDidDisappear so but it inside a container view:
// https://github.com/JetBrains/androidx/blob/jb-main/compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/ComposeWindow.uikit.kt
Expand Down Expand Up @@ -49,9 +50,12 @@ class AvoidDispose: UIViewController {

override func viewSafeAreaInsetsDidChange() {
super.viewSafeAreaInsetsDidChange()
view.setNeedsLayout()
controller.view.setNeedsLayout()
controller.viewWillAppear(false)
RootViewControllersKt.setSafeArea(start: view.safeAreaInsets.left, top: view.safeAreaInsets.top, end: view.safeAreaInsets.right, bottom: view.safeAreaInsets.bottom)
//kotlin compose refresh
controller.view.touchesCancelled([UITouch()], with: UIEvent())
}

override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
17 changes: 17 additions & 0 deletions test/src/androidMain/kotlin/com/rouge41/kmm/compose/Resources.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.rouge41.kmm.compose

import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.res.imageResource

@Composable
internal actual fun imageResource(id: String): ImageBitmap {
val context = Android.context
val id = context.resources.getIdentifier(id, "drawable", context.packageName)
return ImageBitmap.Companion.imageResource(id = id)
}

object Android {
lateinit var context: Context
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.rouge41.kmm.compose

import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.ImageBitmap

@Composable
internal expect fun imageResource(id: String): ImageBitmap
66 changes: 39 additions & 27 deletions test/src/commonMain/kotlin/com/rouge41/kmm/compose/test/App.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.rouge41.kmm.compose.test

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
Expand All @@ -26,23 +29,26 @@ internal fun App() {
val currentRoute = navBackStackEntry?.route?.route
Scaffold(
topBar = {
TopAppBar(
title = { Text(currentRoute ?: "") },
navigationIcon = {
Icon(
Icons.Default.Menu,
"test",
modifier = Modifier.clickable(
onClick = {
scope.launch { scaffoldState.drawerState.open() }
}
Box(modifier = Modifier.background(MaterialTheme.colors.primary)) {
TopAppBar(
modifier = Modifier.padding(top = SafeArea.current.value.calculateTopPadding()),
title = { Text(currentRoute ?: "") },
navigationIcon = {
Icon(
Icons.Default.Menu,
"test",
modifier = Modifier.clickable(
onClick = {
scope.launch { scaffoldState.drawerState.open() }
}
)
)
)
}
)
}
)
}
},
drawerContent = {
LazyColumn {
LazyColumn(modifier = Modifier.padding(top = SafeArea.current.value.calculateTopPadding())) {
items(Demo.values().size) {
val item = Demo.values()[it]
ListItem(
Expand All @@ -58,21 +64,27 @@ internal fun App() {
},
scaffoldState = scaffoldState
) {
NavHost(navigator = navigator, initialRoute = Demo.values().first().toString()) {
NavHost(navigator = navigator, initialRoute = Demo.HelloPlatform.toString()) {
Demo.values().forEach { screen ->
scene(screen.toString()) {
when (screen) {
Demo.LazyColumn -> LazyColumnDemo()
Demo.HelloPlatform -> HelloPlatform()
Demo.Lorem -> Lorem()
Demo.Counter -> Counter()
Demo.Layout -> Layout()
Demo.Images -> Images()
Demo.Buttons -> Buttons()
// Demo.Alert -> Alert()
Demo.TextStyles -> Column { TextStyles() }
Demo.TextFields -> TextFields()
Demo.BottomNavigation -> BottomNavigationDemo()
if (screen == Demo.BottomNavigation) {
BottomNavigationDemo()
} else {
Box(modifier = Modifier.padding(bottom = SafeArea.current.value.calculateBottomPadding())) {
when (screen) {
Demo.LazyColumn -> LazyColumnDemo()
Demo.HelloPlatform -> HelloPlatform()
Demo.Lorem -> Lorem()
Demo.Counter -> Counter()
Demo.Layout -> Layout()
Demo.Images -> Images()
Demo.Buttons -> Buttons()
// Demo.Alert -> Alert()
Demo.TextStyles -> Column { TextStyles() }
Demo.TextFields -> TextFields()
else -> {}
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package com.rouge41.kmm.compose.test

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.runtime.Composable
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.mutableStateOf

internal val safeAreaState = mutableStateOf(PaddingValues())
internal val SafeArea = compositionLocalOf { safeAreaState }

@Composable
internal fun Content() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package com.rouge41.kmm.compose.test.demos

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.rouge41.kmm.compose.test.SafeArea
import moe.tlaster.precompose.navigation.NavHost
import moe.tlaster.precompose.navigation.rememberNavigator

Expand All @@ -16,28 +23,33 @@ internal fun BottomNavigationDemo() {
val currentRoute = navBackStackEntry?.route?.route ?: ""
Scaffold(
bottomBar = {
BottomNavigation {
Tab.values().forEach { screen ->
BottomNavigationItem(
icon = {
Icon(
imageVector = Icons.Default.Home,
contentDescription = null
)
},
label = { Text(screen.toString()) },
selected = currentRoute == screen.toString(),
onClick = {
navigator.navigate(route = screen.toString())
},
selectedContentColor = MaterialTheme.colors.onPrimary,
unselectedContentColor = MaterialTheme.colors.onPrimary.copy(alpha = 0.5f)
)
Box(modifier = Modifier.background(MaterialTheme.colors.primary)) {
BottomNavigation(
modifier = Modifier.height(55.dp + SafeArea.current.value.calculateBottomPadding())
) {
Tab.values().forEach { screen ->
BottomNavigationItem(
modifier = Modifier.padding(bottom = SafeArea.current.value.calculateBottomPadding()),
icon = {
Icon(
imageVector = Icons.Default.Home,
contentDescription = null
)
},
label = { Text(screen.toString()) },
selected = currentRoute == screen.toString(),
onClick = {
navigator.navigate(route = screen.toString())
},
selectedContentColor = MaterialTheme.colors.onPrimary,
unselectedContentColor = MaterialTheme.colors.onPrimary.copy(alpha = 0.5f)
)
}
}
}
}
) {
NavHost(navigator = navigator, initialRoute = Tab.values().first().toString()) {
NavHost(navigator = navigator, initialRoute = Tab.values().first().toString(), modifier = Modifier.padding(bottom = 55.dp + SafeArea.current.value.calculateBottomPadding())) {
Tab.values().forEach { screen ->
scene(screen.toString()) {
when (screen) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
package com.rouge41.kmm.compose.test.demos

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.unit.dp
import com.rouge41.kmm.compose.imageResource
import com.rouge41.kmm.compose.toImageBitmap
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.utils.io.core.*
import com.rouge41.kmm.compose.toImageBitmap

@Composable
internal fun Images() {
Column {
Image(
imageResource("logo"),
null,
modifier = Modifier.width(200.dp).height(300.dp).background(
Color.LightGray
)
)

AsyncImage(
url = "https://loremflickr.com/320/320/ocean",
modifier = Modifier.size(200.dp).background(Color.Black)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,25 @@ import androidx.compose.ui.unit.dp

@Composable
internal fun Layout() {
Column(
modifier = Modifier.fillMaxSize().background(Color.Magenta),
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.CenterHorizontally,
content = {
Text("Layout is the new Blue.", modifier = Modifier.background(Color.Blue), style = TextStyle(color = Color.White))
Text("Green.", modifier = Modifier.background(Color.Green))
Row(
modifier = Modifier.fillMaxWidth().background(Color.Yellow),
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.Bottom,
content = {
Spacer(modifier = Modifier.background(Color.Red).height(30.dp).width(50.dp))
Spacer(modifier = Modifier.background(Color.Black).height(50.dp).width(30.dp))
Spacer(modifier = Modifier.background(Color.Blue).height(10.dp).width(10.dp))
}
)
}
)
Box(modifier = Modifier.background(Color.Green)) {
Column(
modifier = Modifier.fillMaxSize().padding(5.dp).background(Color.Magenta),
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.CenterHorizontally,
content = {
Text("Layout is the new Blue.", modifier = Modifier.background(Color.Blue), style = TextStyle(color = Color.White))
Text("Green.", modifier = Modifier.background(Color.Green))
Row(
modifier = Modifier.fillMaxWidth().background(Color.Yellow),
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.Bottom,
content = {
Spacer(modifier = Modifier.background(Color.Red).height(30.dp).width(50.dp))
Spacer(modifier = Modifier.background(Color.Black).height(50.dp).width(30.dp))
Spacer(modifier = Modifier.background(Color.Blue).height(10.dp).width(10.dp))
}
)
}
)
}
}
24 changes: 24 additions & 0 deletions test/src/iosMain/kotlin/com/rouge41/kmm/compose/Resources.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.rouge41.kmm.compose

import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.toComposeImageBitmap
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.usePinned
import platform.UIKit.UIImage
import platform.UIKit.UIImagePNGRepresentation
import platform.posix.memcpy

@Composable
internal actual fun imageResource(id: String): ImageBitmap {
// TODO: maybe use something more efficient
// TODO: maybe https://github.com/touchlab/DroidconKotlin/blob/main/shared-ui/src/iosMain/kotlin/co/touchlab/droidcon/ui/util/ToSkiaImage.kt
val image = UIImage.imageNamed(id)!!
val data = UIImagePNGRepresentation(image)!!
val byteArray = ByteArray(data.length.toInt()).apply {
usePinned {
memcpy(it.addressOf(0), data.bytes, data.length)
}
}
return org.jetbrains.skia.Image.makeFromEncoded(byteArray).toComposeImageBitmap()
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
package com.rouge41.kmm.compose

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.ui.unit.dp
import com.rouge41.kmm.compose.test.Content
import com.rouge41.kmm.compose.test.safeAreaState
import moe.tlaster.precompose.PreComposeApplication
import platform.CoreGraphics.CGFloat

fun RootViewController() = PreComposeApplication(title = "") {
Content()
}

fun setSafeArea(start: CGFloat, top: CGFloat, end: CGFloat, bottom: CGFloat) {
safeAreaState.value = PaddingValues(start.dp, top.dp, end.dp, bottom.dp)
}

0 comments on commit 3118055

Please sign in to comment.