Is there a GUI component that represents a rectangular container with an optional border (I guess the equivalent of a <div>)?
I see you can have a border with ScrollView although I don’t think you can set properties for the border, and I don’t need the scroll capability in many cases.
If there’s nothing out of the box, what recommendations do you have to create one simply? I’m thinking something where ideally you can specify:
I’m using Views inside layouts a lot, where I might not know (or want to know) the dimensions of the View when I create it. But if I use a UserView, I guess I’d need to know the dimensions?
I was thinking of using a StackedLayout with two views, the view behind being the border. I think the inner view may also need to be nested inside layouts in order to get the dynamic sizing relative to the parent.
This is the closest I can get to the sort of thing I have in mind. The box on the right has a border and everything resizes nicely when you resize the window:
(
~window = Window("What am I doing?").front;
~window.layout = HLayout(
View().background_(Color.blue).minSize_(200@200).maxWidth_(200),
StackLayout(
View().background_(Color(0,0,0,0)).minSize_(200@200),
View().background_(Color.yellow).minSize_(200@200).layout_(
HLayout(View().background_(Color.green))
)
).mode_(1)
);
)
However, the documentation for StackLayout says this:
Unlike other layouts, StackLayout can not contain another layout.
Clearly in my example the StackLayout contains an HLayout, and the thing still works. Perhaps this is okay because the HLayout is not a direct child of the StackLayout?
I’ll keep working and if I can class-ify it to my satisfaction I’ll post it.
And actually, to be precise, I would edit the above with the following: .insetBy so that borderWidth actually shows the whole border, and .joinStyle to clean up the corners.
a hacky workaround might be declaring the border function as this.prDrawBorder or something, and then overloading the .drawFunc method so it looks something like:
…but I would actually consider using object composition (“has” a UserView with a border) instead of subclassing (“is” a UserView with a border), as inheritance can sometimes get a bit messy. Consider taking at look at the helpfile for SCViewHolder for one approach.
I usually set UserView().background_(Color.clear) and then use Pen.fillColor to set the background color of the Rect, should fix the color bleed at the corners
Oh nice, yes I see. And presumably the issue with the background colour could be solved by extending background_ in such a way that it uses the supplied colour to call fillRect on our drawn rectangle, and sets the View’s actual background to transparent.
Thanks, yes, I considered the inheritance vs composition question, but with composition if you wanted something that behaved exactly like a View you’d have to proxy all its members, leading swiftly to a loss of the will to live.
But this actually enforces my point about Class inheritance, once you start overloading methods, it’s hard to stop! So instead of overloading .background for BorderView, you could just call BorderView().view.background to change the background of the UserView. This way, BorderView() might not behave exactly like view, but BorderView().viewis a View/UserView, so you get everything for free by defining one method:
And the good thing with SCViewHolder is that it forwards unknown messages to the view, so if BorderView would be an SCViewHolder subclass, you could just write BorderView().background.