Skip to content

Commit

Permalink
adjust underline and focus width, track X position of tap and hover
Browse files Browse the repository at this point in the history
  • Loading branch information
dweymouth committed Oct 15, 2023
1 parent ccc6a1c commit 2df2a5f
Showing 1 changed file with 33 additions and 11 deletions.
44 changes: 33 additions & 11 deletions widget/hyperlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Hyperlink struct {
// Since: 2.2
OnTapped func() `json:"-"`

textWidth float32 // updated in syncSegments
focused, hovered bool
provider *RichText
}
Expand Down Expand Up @@ -67,7 +68,10 @@ func (hl *Hyperlink) CreateRenderer() fyne.WidgetRenderer {

// Cursor returns the cursor type of this widget
func (hl *Hyperlink) Cursor() desktop.Cursor {
return desktop.PointerCursor
if hl.hovered {
return desktop.PointerCursor
}
return desktop.DefaultCursor
}

// FocusGained is a hook called by the focus handling logic after this object gained the focus.
Expand All @@ -83,13 +87,18 @@ func (hl *Hyperlink) FocusLost() {
}

// MouseIn is a hook that is called if the mouse pointer enters the element.
func (hl *Hyperlink) MouseIn(*desktop.MouseEvent) {
hl.hovered = true
func (hl *Hyperlink) MouseIn(e *desktop.MouseEvent) {
hl.hovered = hl.isPosOverText(e.Position)
hl.BaseWidget.Refresh()
}

// MouseMoved is a hook that is called if the mouse pointer moved over the element.
func (hl *Hyperlink) MouseMoved(*desktop.MouseEvent) {
func (hl *Hyperlink) MouseMoved(e *desktop.MouseEvent) {
oldHovered := hl.hovered
hl.hovered = hl.isPosOverText(e.Position)
if hl.hovered != oldHovered {
hl.BaseWidget.Refresh()
}
}

// MouseOut is a hook that is called if the mouse pointer leaves the element.
Expand All @@ -98,6 +107,10 @@ func (hl *Hyperlink) MouseOut() {
hl.BaseWidget.Refresh()
}

func (hl *Hyperlink) isPosOverText(pos fyne.Position) bool {
return pos.X <= hl.textWidth+theme.Padding()*2
}

// Refresh triggers a redraw of the hyperlink.
//
// Implements: fyne.Widget
Expand Down Expand Up @@ -156,12 +169,18 @@ func (hl *Hyperlink) SetURLFromString(str string) error {
}

// Tapped is called when a pointer tapped event is captured and triggers any change handler
func (hl *Hyperlink) Tapped(*fyne.PointEvent) {
func (hl *Hyperlink) Tapped(e *fyne.PointEvent) {
if !hl.isPosOverText(e.Position) {
return
}
hl.invokeAction()
}

func (hl *Hyperlink) invokeAction() {
if hl.OnTapped != nil {
hl.OnTapped()
return
}

hl.openURL()
}

Expand All @@ -172,7 +191,7 @@ func (hl *Hyperlink) TypedRune(rune) {
// TypedKey is a hook called by the input handling logic on key events if this object is focused.
func (hl *Hyperlink) TypedKey(ev *fyne.KeyEvent) {
if ev.Name == fyne.KeySpace {
hl.Tapped(nil)
hl.invokeAction()
}
}

Expand All @@ -196,6 +215,7 @@ func (hl *Hyperlink) syncSegments() {
},
Text: hl.Text,
}}
hl.textWidth = fyne.MeasureText(hl.Text, theme.TextSize(), hl.TextStyle).Width
}

var _ fyne.WidgetRenderer = (*hyperlinkRenderer)(nil)
Expand All @@ -212,11 +232,13 @@ func (r *hyperlinkRenderer) Destroy() {
}

func (r *hyperlinkRenderer) Layout(s fyne.Size) {
innerPad := theme.InnerPadding()
r.hl.provider.Resize(s)
r.focus.Move(fyne.NewPos(theme.InnerPadding()/2, theme.InnerPadding()/2))
r.focus.Resize(fyne.NewSize(s.Width-theme.InnerPadding(), s.Height-theme.InnerPadding()))
r.under.Move(fyne.NewPos(theme.InnerPadding(), s.Height-theme.InnerPadding()))
r.under.Resize(fyne.NewSize(s.Width-theme.InnerPadding()*2, 1))
r.focus.Move(fyne.NewPos(innerPad/2, innerPad/2))
w := fyne.Min(s.Width, r.hl.textWidth+innerPad+theme.Padding()*2)
r.focus.Resize(fyne.NewSize(w-innerPad, s.Height-innerPad))
r.under.Move(fyne.NewPos(innerPad, s.Height-innerPad))
r.under.Resize(fyne.NewSize(w-innerPad*2, 1))
}

func (r *hyperlinkRenderer) MinSize() fyne.Size {
Expand Down

0 comments on commit 2df2a5f

Please sign in to comment.