fyne icon indicating copy to clipboard operation
fyne copied to clipboard

Add full rich text to text entry widget

Open rasteric opened this issue 6 years ago • 13 comments

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.

rasteric avatar Oct 05 '18 21:10 rasteric

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 :)

andydotxyz avatar Oct 05 '18 21:10 andydotxyz

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 avatar Oct 20 '18 18:10 andydotxyz

@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?

stuartmscott avatar Mar 31 '20 20:03 stuartmscott

Oops, that was a typo in the commit message I guess

andydotxyz avatar Mar 31 '20 20:03 andydotxyz

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.

carwyn avatar Dec 22 '20 01:12 carwyn

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.

mrjrieke avatar Mar 11 '21 15:03 mrjrieke

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

andydotxyz avatar Mar 12 '21 12:03 andydotxyz

I eagerly await the rich text solution you suggested.

mrjrieke avatar Mar 13 '21 14:03 mrjrieke

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
}

andydotxyz avatar Apr 04 '21 15:04 andydotxyz

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.

niondir avatar Jul 16 '21 22:07 niondir

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.

andydotxyz avatar Aug 23 '21 15:08 andydotxyz

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.

bon-ami avatar Jul 15 '22 07:07 bon-ami

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.

andydotxyz avatar Jul 15 '22 15:07 andydotxyz