Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to choose a text size for label widgets #5561

Closed
2 tasks done
ErikKalkoken opened this issue Feb 26, 2025 · 5 comments
Closed
2 tasks done

Add ability to choose a text size for label widgets #5561

ErikKalkoken opened this issue Feb 26, 2025 · 5 comments

Comments

@ErikKalkoken
Copy link
Contributor

Checklist

  • I have searched the issue tracker for open issues that relate to the same feature, before opening a new one.
  • This issue only relates to a single feature. I will open new issues for any other features.

Is your feature request related to a problem?

The Label widget currently supports one text size only (size 14 in the default Fyne theme).

However, users may want to render text in different sizes in their apps. For example I made a mail client with Fyne and wanted to render the subject text with in a larger size then the body text. I ended up re-creating the label widget, so I can use the same API but have different sizes. (See example screenshot below).

I am aware that a similar feature has been requested before and that this may be a bit of a controversial topic. But I think I can propose a solution that satisfies both the apparent wish for such a feature from the user community and and still ensure it would not break the theme.

Example

A mail client with different text sizes:

Image

Is it possible to construct a solution with the existing API?

Yes, there are three alternatives, but they each have significant disadvantages.

canvas.Text

First, one can create a text of any size with canvas.Text:

x := canvas.NewText("Heading", theme.Color(theme.ColorNameForeground))
x.TextSize = 20

However, these objects require the user to manually integrate them into the current theme (padding, color, size, ...). It also lacks all the advanced API features of a label like for example data binding, which again the user has to add manually. Other important feature like truncation are also missing too.

In my opinion canvas.Text is a low-level primitive, that should not be used directly in an app, but instead for building custom widgets. I also think that new users looking for a solution might often end up using this primitive and then get poor results.

widget.RichText with markdown

Second, one can use a widget.RichText with Markdown to create larger text sizes:

widget.NewRichTextFromMarkdown("# Heading")

This is much better then using canvas.Text, since it has theming, truncation and wrapping. But it still lacks some important features of the label API, e.g. data binding. The approach also feels a bit like a hacky.

widget.RichText with segments

Third, one can construct a text with a custom size through widget.RichText and segments:

widget.NewRichText(&widget.TextSegment{
	Style: widget.RichTextStyle{
		SizeName: theme.SizeNameHeadingText,
	},
	Text: "Heading",
})

This also is much better then using canvas.Text, since it also has theming, truncation and wrapping. This approach also does not feel like a hack. Seasoned Fyne developed will recognize this the same approach used by widget.Label under the hood. However, this approach is very verbose and probably not very accessible to Fyne beginners. The RichText API itself is also not that easy to work with for a single piece of text, since it is designed to work with larger texts consisting of multiple segments. e.g. changing the text required something like this:

x.Segments[0].(*widget.TextSegment).Text = "Other text"

And the API also lacks comfortable features like data binding.

Describe the solution you'd like to see.

I would suggest adding the following function to the label API:

func NewLabelWithSize(text string, sizeName fyne.ThemeSizeName) *Label{
    ...
}

This function would create a new widget.Label, but only accept text related sizes,. Those currently are:

Name Size
SizeNameCaptionText 11
SizeNameHeadingText 24
SizeNameSubHeadingText 18
SizeNameText 14

This will ensure that any label created with this new function would still fit nicely into the current theme, since it would use the same text sizes, which are already used by other Fyne widgets, e.g. widget.Card.

In addition I would propose to add SizeName as a public field. This would enable users to use the new size feature together with data binding.

In case this proposal is met with positive feedback, I would also offer to implement it.

@andydotxyz
Copy link
Member

Interesting. You're right the RichText is the way to go but I agree that the API is much more complex than Label.

I can see the logic in exposing a single TextSizeName or similar - but the question would be where does it stop. Where does RichText stop being useful because Label gets too complex.

If this is the only thing lacking in Label we can look at this as-is but I want to make sure it is considered carefully because Label is meant to be trivial just like Button - to do a single job well and in a standard way.

@dweymouth
Copy link
Contributor

Another option could be additional convenience constructors for RichText for creating single-segment texts

widget.NewRichTextWithSize(text string, sizeName fyne.ThemeSizeName)

widget.NewRichTextWithSizeAndStyle(text string, sizeName fyne.ThemeSizeName, style fyne.TextStyle)

@dweymouth
Copy link
Contributor

Though now that Label will have selection as well it may be more useful to have the size / style customizations available there... 🤔

@andydotxyz
Copy link
Member

Though now that Label will have selection as well it may be more useful to have the size / style customizations available there... 🤔

That shouldn't be a consideration - Once we have a RichTextEntry then the selection would work for RichText too. Until then the varying text size is a complication that selection code doesn't work with.

@dweymouth
Copy link
Contributor

Label could always be a single text size/style - I think that is the fundamental difference between Label and RichText. With selection support landing, if the user wants to have selectable larger text, or selectable bold text, the only way to do that would be put a label in a ThemeOverride container with a custom theme -- even more of a verbose and "hacky"-seeming workaround than what Erik described above. I think it only strengthens the argument to have size and style customization available on the Label widget.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants