Can i implement margin without wrapping my view wi...
# doodle
c
Can i implement margin without wrapping my view within a container or another view. I thought I could use
view.bounds
but couldn't so far
n
So you’d like other views to be spaced away from your view by some distance? if so, you can control this using a
Layout
. the layout in your view’s container (or the
Display
if your view is top-level) can makes sure your views siblings are spaced away from it however you’d like. the layout does this by specifying the
bounds
of all the views within a container.
see this section in the docs if you haven’t used layouts before.
c
Okay i guess it can only be done during layout right?
n
the reasoning here is that views don’t know how they will be contained and which parents they will have. so they don’t really have a much say in their own layout (except for stating their ideal/minSize etc.). you can always create custom views that do have a padding property and use that in your layouts. but it’s something the framework leaves out for the reason i mentioned above.
c
Hi @Nick i tried to do something like this:
Copy code
view.displayRect.rounded { index: Int, point: Point ->
    20.0
}
To change the rounded corners. It didnt work though My questions: 1. What does that function do 2. How can i round the corners of a view
n
Hey @Cherrio LLC. This lets you create a path with configurable rounded corners from any Polygon (including Rectangle). It doesn't change the Polygon itself, just creates a new Path from it. This is useful if you want to round the corners of of something like a star shape etc.. And it works by letting you return a radius for each corner, the index of the point and it's value are passed and you return a radius you want it to have. To your question... Rounding the corners of a View really means drawing a rounded rect instead of one w/ no rounding. There are a few ways to do this, but the easiest and most performant is to do the following somewhere in your rendering of that view:
Copy code
override fun render(canvas: Canvas) {
    canvas.rect(bounds.atOrigin, radius = 20.0, ...)
}
You could also render the rect as a Path if the corners need different radii. This is where you'd use the method you asked about:
Copy code
override fun render(canvas: Canvas) {
    // As usual, we use atOrigin b/c bounds is actually defined in the parent coordinate space, which means
    // it has an x,y position. All we need is a rect the size of the view at 0,0
    val path = bounds.atOrigin.rounded { index, _ ->
        when (index) {
            0, 2 -> 20.0 // round 1st and 3rd corners with larger radius
            else -> 10.0
        }
    }

    // the result is a path we can now render
    canvas.path(path, fill = Red.paint)
}
Of course you might want to cache the path and only regenerate it on boundsChanged to make this a bit more performant.
c
I can't have access to canvas after the view has been rendered right??
n
No. What are you trying to do?
c
I wanted to change the shape of the view when a value changes.
n
Then you'll have to rerender. You can do this automatically using a
renderProperty
if you're changing a single value. Or you could use
observable
for the changed value and recalculate your path (assuming you're doing what you asked about above). That path could be the
renderProperty
so that setting it triggers a rerender:
Copy code
// this will trigger repaint if the path updates
private var path by renderProperty(computePath())

// re-compute path on changes to your value
private var value by observable(...) { _, new ->
    path = computePath()
}
    
private fun computePath(): Path {
    ...
}
c
Yeah that's what we ended up doing. Thanks
Can rect draw a circle if parameters are right? or we'll have to use
canvas.circle()
?