Skip to content

Textgrid CursorLocationForPosition reports wrong location when scrolled #5745

@redawl

Description

@redawl

Checklist

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

Describe the bug

While implementing text highlighting inside a textgrid, I noticed that Textgrid.CursorLocationForPosition reports the incorrect row and col when the widget is scrolled away from the default location. This causes highlighting of the incorrect cell.

This is when using any Scroll, besides fyne.ScrollNone

How to reproduce

  1. Create a custom widget using Textgrid as the BaseWidget. Instantiate TextGrid with a Scroll of ScrollBoth, ScrollHorizontalOnly, or ScrollVerticalOnly.
  2. Implement the Hoverable interface, and log the result of CursorLocationForPosition in the MouseMoved handler.
  3. Observe that the Cursor location reported is correct when the widget is not scrolled from the default location, but is incorrect when scrolled away from the default location.

Screenshots

No response

Example code

package main

import (
	"fmt"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/driver/desktop"
	"fyne.io/fyne/v2/widget"
)

var _ desktop.Hoverable = (*TextgridWrapper)(nil)

type TextgridWrapper struct {
	widget.TextGrid
}

func (t *TextgridWrapper) MouseIn (evt *desktop.MouseEvent) {}
func (t * TextgridWrapper) MouseMoved(evt *desktop.MouseEvent) {
	row, col := t.CursorLocationForPosition(evt.Position)
	fmt.Printf("Reported location: row = %d, col = %d\n", row, col)
}
func (t *TextgridWrapper) MouseOut() {}

func main() {
	a := app.New()
	w := a.NewWindow("Test")
	longText := "dawdawdadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" // Put some looooong text in here...


	textGridWrapper := &TextgridWrapper{
		TextGrid: widget.TextGrid{
			Scroll: fyne.ScrollBoth,
		},
	}
	label := widget.NewLabel(longText[0:len(longText) / 2])
	textGridWrapper.SetText(longText)
	layout := container.NewBorder(label, nil, nil, nil, textGridWrapper)

	w.SetContent(layout)
	w.ShowAndRun()
}

Fyne version

v2.6.0

Go compiler version

1.24.2

Operating system and version

Gentoo

Additional Information

I do currently have a workaround. I implemented a wrapper CursorLocationForPosition for my custom widget that extends Textgrid:

func (p *PacketEntry) CursorLocationForPosition(pos fyne.Position) (row, col int) {
	cellSize := p.TextGrid.PositionForCursorLocation(1, 1)
	y := pos.Y
	x := pos.X

	if p.scroll != nil && p.scroll.Visible() {
		y += p.scroll.Offset.Y
		x += p.scroll.Offset.X
	}

	row = int(y / cellSize.Y)
	col = int(x / cellSize.X)
	return
}

This requires using an external container.Scroll, instead of the one embedded in Textgrid.

While debugging, I noticed that regardless of the scroll visually, the internal Textgrid scroll X and Y are always 0. I think that is part of the issue, but the calculation used is also incorrect.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions