WIP - multi hyperlink

This commit is contained in:
Drew Weymouth
2023-10-22 11:10:36 -07:00
parent 6f08032f22
commit c3143dbbbe
5 changed files with 109 additions and 94 deletions
+96
View File
@@ -0,0 +1,96 @@
package widgets
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/widget"
)
type MultiHyperlink struct {
widget.BaseWidget
Segments []MultiHyperlinkSegment
OnTapped func(string)
provider *widget.RichText
}
type MultiHyperlinkSegment struct {
Text string
LinkID string
}
func NewMultiHyperlink() *MultiHyperlink {
c := &MultiHyperlink{
provider: widget.NewRichText(),
}
c.ExtendBaseWidget(c)
c.provider.Wrapping = fyne.TextTruncate
return c
}
func (c *MultiHyperlink) syncSegments() {
l := len(c.provider.Segments)
for i, seg := range c.Segments {
appendingSegments := 2*i >= l // true if we need to extend the RichText provider with new segments
var rtSeg widget.RichTextSegment
if !appendingSegments {
rtSeg = c.provider.Segments[2*i]
} else if i > 0 {
// append new separator segment
c.provider.Segments = append(c.provider.Segments, c.newSeparatorSegment())
}
if seg.LinkID == "" {
rtSeg = c.updateOrReplaceTextSegment(rtSeg, seg.Text)
} else {
rtSeg = c.updateOrReplaceHyperlinkSegment(rtSeg, seg.Text, seg.LinkID)
}
if appendingSegments {
c.provider.Segments = append(c.provider.Segments, rtSeg)
} else {
c.provider.Segments[2*i] = rtSeg
}
}
// discard extra segments if shortening the multihyperlink
for i := 2 * len(c.Segments); i < l; i++ {
c.provider.Segments[i] = nil
}
c.provider.Segments = c.provider.Segments[:2*len(c.Segments)-1]
}
func (c *MultiHyperlink) newSeparatorSegment() widget.RichTextSegment {
return &widget.TextSegment{Text: ", ", Style: widget.RichTextStyle{Inline: true}}
}
func (c *MultiHyperlink) updateOrReplaceTextSegment(seg widget.RichTextSegment, text string) widget.RichTextSegment {
if seg != nil {
if ts, ok := seg.(*widget.TextSegment); ok {
ts.Text = text
return seg
}
}
return &widget.TextSegment{Text: text, Style: widget.RichTextStyle{Inline: true}}
}
func (c *MultiHyperlink) updateOrReplaceHyperlinkSegment(seg widget.RichTextSegment, text, linkID string) widget.RichTextSegment {
if seg != nil {
if ts, ok := seg.(*widget.HyperlinkSegment); ok {
ts.Text = text
// TODO: OnTapped
return seg
}
}
return &widget.HyperlinkSegment{Text: text} // TODO: OnTapped
}
func (c *MultiHyperlink) onSegmentTapped(linkID string) {
// TODO
}
func (c *MultiHyperlink) Refresh() {
c.syncSegments()
c.BaseWidget.Refresh()
}
func (c *MultiHyperlink) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(c.provider)
}