fyne
fyne copied to clipboard
Add full rich text to text entry widget
I know it's a very complex control but I'd still suggest, for the future, a multiline text entry field with the following rich text features:
- text styles bold, underline, italic; sticky and non-sticky
- text color
- different fonts in one field
- paragraph alignment
- simple inline images, for many purposes an option to add an image in a line is enough, where the surrounding text is aligned bottom, center, or top
- "standard" import/export format: html, xml, rtf, markdown, or whatever else you think is best, but not something totally non-standard
- custom data ranges with an option to extend them when writing text (like a sticky style) and an option for mouse callbacks/clickbacks
The last one requires explanation. An entry field should allow some way to add custom data to ranges of glyphs and some way of retrieving it by cursor position or mouse position. This is hard to implement later by a user of the library without access to the underlying implementation, because that would require one to maintain some parallel data structure and capture all edit events. If you miss one way the text might be changed, then the data structures get our of sync, so it's much better to have a way to add more functionality directly with the styled text. I'm thinking about hyperlinks, tooltips, etc.
Background: The reason I add this very general feature request is that I've seen dozens of handmade GUI libraries for various languages, and they all lack in the above functionality. So people turn to Qt or browser-based overblown solutions instead.
This is a really great suggestion and we will work toward it slowly. The canvas text object will only ever support 1 set of styles per block of text (to keep the backends simple) but we can do lots of cool stuff in Go.
The widget.Label has recently added multi line so you can see how this is started - we add (with lots of tests) the layout code and the application of styles (through an API or a markup) which will then apply to label and entry.
I agree that this is something many toolkits lack, but it is very hard to get right and keep efficient. Let's make it happen :)
Work has also begun on the cursor handling in widget.Entry. Once that is complete we should be able to start work on how rich / marked up text be supported...
@andydotxyz I'm not sure https://github.com/fyne-io/fyne/commit/263a14d18b4bd12ab8644a61bd5b9de9840162f7 fixes this issue since it is concerned with select box and not entry/label. Should this issue be reopened?
Oops, that was a typo in the commit message I guess
Arguably #1447 is related to this. As mentioned there there isn't currently a mono-spaced editor widget but TextGrid is able to display mono-space. A basic example use case is a simple text editor for editing config files or perhaps as a base for a simple code editor. This would fit nicely into fynedesk much like notepad does in Windows or gedit in Gnome.
I've spent quite a lot of thought over the last few days on this because it's something I really need. I'm kind of trying to work with the existing fyne widgets to frankenstein what I need.
One idea I like is that content is represented by a giant slice(able) array of runes. Then the styling of the slice and (subslices) is determined by a separate index stack where for each entry in the stack it specifies the beginning index and ending index and the style to apply. That way, the edit content itself doesn't need to be broken up.
Another idea I had was playing with the idea of using a variant of GridWrapLayout to make this happen with unfortunately very ugly results (since gridwraplayout has fixed cell sizes). So, essentially a grid of Entry widgets that are arranged adjacently. The trick comes when you want to move the cursor transparently between the different entry boxes. :)
An enhanced wrapping HBoxLayout might work better since sub elements can be sized and even styled independently. Again problems with edit cursor movement between Edit elements.
Thanks for the thoughts. I just don't think we can make a good experience with multiple entry widgets. Once we have a good API for handling rich text rendering it may be clearer how to manage the editing of it. See #2074
I eagerly await the rich text solution you suggested.
Possible API that I have just been looking at:
var (
RichTextStyleInline RichTextStyle
RichTextStyleParagraph RichTextStyle
RichTextStyleHeading RichTextStyle
RichTextStyleSubHeading RichTextStyle
RichTextStyleQuote RichTextStyle
RichTextStyleURL RichTextURL
RichTextStyleEmphasis RichTextStyle
)
type RichText struct {
BaseWidget
Segments []RichTextSegment
}
type RichTextSegment interface {
TextRepresentation() string
CanvasRepresentation() fyne.CanvasObject
}
type TextSegment struct { // would implement RichTextSegment, handles rendering text
Text string
Type RichTextStyle
}
type RichTextStyle struct {
Alignment fyne.TextAlign
ColorName ThemeColorName
Inline bool
TextSize float32
TextStyle fyne.TextStyle
}
type RichTextURL struct {
RichTextStyle
URL url.URL
}
type HorizontalRuleSegment struct { // would implement RichTextSegment, just draws a line
}
I need the same.
Looking for a Scrolling box with selectable but read-only mono-spaced text for a Log View.
A feature with ScrollToLine(n int)
or SetCursorToLine(n int)
would be very helpful as well to guide the user to a specific line, e.g. scroll to bottom, top or a search result inside the text.
In 2.1 we add the rich text APIs, but they will not be exposed through Entry until a future release, as the cursor management etc is more complex.
I've checked for many days and could not find how to set a font for a (Rich-)Text/Entry control. Can I expect for it on a future release please? Thanks.
I've checked for many days and could not find how to set a font for a (Rich-)Text/Entry control. Can I expect for it on a future release please? Thanks.
The font used in Entry matches the rest of the app and is set by the theme. To modify the styles of items inside an entry will indeed need a rich text editor, which this ticket tracks. You can see that it is currently assigned to "Cragganmore (est Sept 2022)" which is the plan as it stands.