Finally designing a watch face with ease, with com...
# compose-wear
l
Finally designing a watch face with ease, with compose. Instant preview in the IDE, and runs just fine as a Watch Face on actual watches. Thanks to @mmartos for the building https://github.com/manuel-martos/compose-clock which is the base design in this video.
🎉 6
👍 3
🙌 4
y
This is so compelling. I'll try to contribute back some screenshot generation for playstore
❤️ 1
y
I am super interested in using compose canvas to make WatchFace. How can I do that?
If this is possible, can I use compose canvas also for Tiles?
y
Yes, there is a Horologist module for that.
An old sample - packages might have changed https://github.com/google/horologist/pull/249
image.png
Copy code
internal fun imageResource() = canvasToImageResource(Size(100f, 100f), Density(context)) {
        // draw operations here
    }
y
Thanks Yuri, I see that I still need to use the compose canvas to generate ImageResource for that. So it is also how the WatchFace use the compose canvas works?
y
No.
The Tiles one has the Compose DrawScope API, without state tracking. Single shot, turned into a byte[] and sent in image resources. No compose state magic, no updates.
@louiscad compose watchfaces will feel like Compose magic, state tracking etc.
But if you want something simple like generate a static image like a chart, with rarely updating date, it will be almost the same.
y
Thanks Yuri, @louiscad I am looking forward to knowing more about how you did that.
1
l
@Yingding Wang Are you interested in it for personal use only, or do you want to publish a watch face app with it on the Play Store?
a
Is this an actual watchface or just a clock app? Can you now create watchfaces with Jetpack Compose? If so, are there any examples/resources available?
l
It's both
The SDK is not released yet, I'm working on it
🙌 1
a
Whenever you have a preview ready, I'll be happy to test. I just gave Watch Face Studio a try, and I'm not impressed 😕
😞 1
💡 1
l
I also tried WFF, even made a Kotlin DSL for it, and I've been unimpressed as well, that's why I pivoted and made Compose O'Clock. WFF could be cooler with an on-device API though, but it doesn't exist yet, and interactivity is really nice.
1
WFF being the XML output of Samsung Watch Face Studio, compatible only with Wear OS 4 (only 64 bit CPUs)
Hello! Compose O'Clock has been released! You can now build Watch Faces with Compose Canvas and Compose runtime. Instant preview in the IDE, and lots of other goodness! https://github.com/Splitties/ComposeOClock
👏🏾 1
wearos 5
😮 3
👏🏼 1
4
🚀 3
👏 6
jetpack compose 10
❤️ 3
🦜 5
l
Does anyone have any practical guidance on how to use OpenGL in tandem with Compose?
l
For a Watch Face? It's unfortunately not possible, because of limitations in androidx.wear.watchface.
y
I suspect if you want something past AGSL Shaders, then you need a SurfaceView/TextureView?
l
Which you can't use inside a WatchFace. Only the GL ES Watch Face renderer would do, and it's not possible to get a Canvas there AFAIK.
l
I thought about using the OpenGL
Renderer.GlesRenderer2
and creating a bitmap texture there that would be the target for Compose rendering...
l
You mean as a
Brush
?
l
I was able to use a classic
Canvas
with this approach, however, text drawing etc. in Canvas is limited. Arbitrary Compose to Bitmap would be a lot better, but I haven't looked much if it is possible to rasterize Compose like that.
y
They added an API for that
👀 1
l
There's some leftover experiment with AGSL shaders here. When it's not too GPU intensive, it works fine on a Watch Face. If you try them, you'll see some work smoothly, some don't. You probably wouldn't want to use them in ambient mode, and test performance and power consumption in interactive mode. https://github.com/Splitties/ComposeOClock/blob/47b54181b1c8bfd534457b001218477258b95d6c/shared/src/main/kotlin/cleanthisbeforerelease/experiments/ShadersExperiments.kt
y
You can capture a composable via a modifier.
l
Modifier from Compose work only in a View, which you can't use inside a WatchFace, because it's not a View, and can't host one.
y
But not for watchfaces
l
But I know a way to capture something drawn from Compose O'Clock and create a Bitmap with it, and probably it'd be possible to get that inside a GL ES Watch Face renderer.
l
Basically to be clear, I'd like to render something using OpenGL and then draw a UI overlay on top of it, preferably using Compose 😄
l
That's what I expected
And it's not so easy to do. Do you want to make a product out of it?
You want that inside a Watch Face, correct?
l
Yes. I have this watch face with a globe that was supposed to be a clutter-free way to portray the current time, but it turns out a way to display a clock there is sometimes more practical 😄 Just Globe - Earth Watch Face - Apps on Google Play
👀 2
a
For https://github.com/alexvanyo/composelife I went down the route of using
GlesRenderer2
and using the Compose snapshot state system to drive the state management for what I render in OpenGL in the watchface. Which definitely isn't quite the same as using Compose's UI library to drive the pixels on a watchface.
👀 1
K 1
y
That's awesome. Surprised I hadn't seen it. Will spelunk around
a
Actually I totally forgot I had to tackle drawing a
Canvas
into
GlesRenderer2
already for rendering complications: https://github.com/alexvanyo/composelife/blob/562e40704ea74c724eb0d694d836c7a43b2c[…]n/com/alexvanyo/composelife/wear/watchface/ComplicationShape.kt So if you can get the Compose UI rendering into a
Canvas
, you can render it as a texture into OpenGL with a bit of work
y
So basically within the Watchface service, in the draw calls, you can safely make static calls to GLES?
Copy code
GLES20.glDrawElements(
            GLES20.GL_TRIANGLES,
            drawOrder.size,
            GLES20.GL_UNSIGNED_SHORT,
            drawListBuffer,
        )
a
In the
Renderer.GlesRenderer2.render
yep, you can call into GLES to draw things
y
The complication threw me. That's just standard calls for a Gles watchface. Ignore my stupid questions