Hi, i am currently making a 'dialog' system for use in my program,
and i've been finding it difficult to figure out a correct size,
as most messages can be longer than the already hard-coded window size.
Is it possible to automatically get maximum width or height for a given
text and a label method (eg. material.Body1) so i can use the maximum
to set the window size accordingly?
In other words, how can i dynamically make a window in which the
dimensions
are appropiately sized to the height/lines of a message?
thanks
On Thu, Dec 21, 2023 at 10:33 AM sewn <sewn@disroot.org> wrote:
>> Hi, i am currently making a 'dialog' system for use in my program,> and i've been finding it difficult to figure out a correct size,> as most messages can be longer than the already hard-coded window size.>> Is it possible to automatically get maximum width or height for a given> text and a label method (eg. material.Body1) so i can use the maximum> to set the window size accordingly?>> In other words, how can i dynamically make a window in which the> dimensions> are appropiately sized to the height/lines of a message?
Well, you can construct a text shaper (or a theme type) without
opening a window, so there's no obstacle to shaping some text in a
text widget in order to determine its dimensions. The tricky thing
would be deciding what maxWidth to use. Text wraps lines at some max
width, and you probably want to constrain it so that you don't end up
with an absurdly wide window.
var ops op.Ops
th := material.NewTheme()
gtx := layout.Context{ // fill in values to provide maximum allowed sizes }
dims := material.Body1(th, "foo").Layout(gtx)
ops.Reset()
// now you have dims, the dimensions of the text.
w := app.NewWindow(app.Size(unit.Dp(dims.Size.X), unit.Dp(dims.Size.Y)))
The other challenge is around the difference between screen pixels and
Dp. Window sizes are specified in Dp, but widget dimensions are
provided in pixels. Without a window already open, you can't know the
scaling factor in use. Probably the best option is to shape the text
assuming the scaling factor is 1, then get the size and specify that
the window should be that size in Dp. Once the window is open and you
have the true scaling factor, adjust the text size that you display
your message at using the scaling factor so that it fills the space as
expected.
Cheers,
Chris
On Thu Dec 21, 2023 at 8:18 PM +03, Chris Waldon wrote:
> var ops op.Ops> th := material.NewTheme()> gtx := layout.Context{ // fill in values to provide maximum allowed sizes }> dims := material.Body1(th, "foo").Layout(gtx)> ops.Reset()>> // now you have dims, the dimensions of the text.
Thanks alot! i was actually doing this exact same thing, i just hadn't filled the
Constraints member of context, which is why i was confused when the dimensions were 0..
Just a small question though, does the Context used to get the maximum height can be used
again within the event loop? or is it only used once just to retrieve the height?
I assume the answer is no, as the context also needs the event members and such.
On Thu, Dec 21, 2023 at 2:15 PM sewn <sewn@disroot.org> wrote:
>> Just a small question though, does the Context used to get the maximum height can be used> again within the event loop? or is it only used once just to retrieve the height?>> I assume the answer is no, as the context also needs the event members and such.
You should just make a new gtx with the frame event like normal.
You're right that you want to make sure it's synced with all of the
frameevent's fields. Making a gtx is not expensive (it isn't a
GPU-side resource or anything).
Cheers,
Chris
On Fri, Feb 9, 2024 at 1:44 AM sewn <sewn@disroot.org> wrote:
>> How are you supposed to retrieve the scaling factor?
The system.FrameEvent.Metrics field provides everything you should
need for that.