chrisbanes / haze

A blurring modifier for Compose Multiplatform / Jetpack Compose
https://chrisbanes.github.io/haze/
Apache License 2.0
1.12k stars 30 forks source link

Preview Fails to Render #71

Closed jakobulbrich closed 9 months ago

jakobulbrich commented 9 months ago

The Preview in Android Studio for Jetpack Compose fails to render when using the .haze(...) Modifier:

java.lang.IllegalArgumentException: Software rendering doesn't support drawRenderNode
   at android.graphics.Canvas.drawRenderNode(Canvas.java:2329)
   at dev.chrisbanes.haze.HazeNode31.draw(HazeNode31.kt:125)

This could be solved by wrapping the haze modifier in a if (!LocalInspectionMode.current) { ... } but it's not the most elegant solution to repeat this over and over again on caller side.

Version: 0.4.1 Artifact: dev.chrisbanes.haze:haze-jetpack-compose

--

In general the Preview support could be improved. We are facing the following issues challenges:

  1. Preview does not work at all (see exception above)

  2. Background for Preview of hazeChild When applying the haze Modifier only if !LocalInspectionMode.current, then the hazeChild has a transparent background in the preview, since the background/tint color is configured on haze Modifier side. Adding a background for Preview purposes, could be solved by using if (!LocalInspectionMode.current) { hazeChild(...) } else { background(backgroundColor) }. Which is not optimal since we need to duplicate the background color.

  3. Preview across components/files Sometimes we do have the haze Modifier in one file (e.g. the screen with a lazy column) and the hazeChild in another (e.g. the bottom navigation which is embedded in multiple screens). With this setup it is also difficult to provide a proper preview with a background for the hazeChild component. Currently we are passing the HazeState as a parameter to this component, provide a dummy state in the Preview and switch to a solid background if we are in inspection mode.

chrisbanes commented 9 months ago

Thanks for the report!

This is tricky as the Modifier.Node APIs don't make it easy to delegate based on a composition local value. We can use DelegatingNode and DelegatableNode, but it's going to require a large refactoring of the codebase for it to work. The short summary is that we'll need to create a wrapper DelegatingNode, which delegates to HazeNode31 or HazeNodeBase based on the value of SDK_INT and LocalInspectionMode. That will fix issue 2.

I don't think there's much we can do about issue 3. There is a coupled relationship between haze and hazeChild and I don't want to create hacks just for previews.

chrisbanes commented 9 months ago

For now, I'm going to fix the crash by no-op'ing the main haze modifier when LocalInspectionMode is true.

jakobulbrich commented 9 months ago

For now, I'm going to fix the crash by no-op'ing the main haze modifier when LocalInspectionMode is true.

Thanks for the quick fix. Now at least the preview does not crash anymore 👍 Would be very nice to have this delegation to HazeNode31 or HazeNodeBase also depending on LocalInspectionMode.

I don't think there's much we can do about issue 3. There is a coupled relationship between haze and hazeChild and I don't want to create hacks just for previews.

It would be nice if we could configure the tint color on hazeChild side. But I guess it is not easily possible, unless we are using the HazeState just as a registry to pass the bounds and desired tint color. But this raises the question how it behaves if multiple colors are set for the same area by different children and if the order of drawing them could be guaranteed.