Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding scrolling to TextGrid and a new Append method too #5434

Merged
merged 10 commits into from
Jan 24, 2025

Conversation

andydotxyz
Copy link
Member

Super fast monospace text is now possible.

Congratulations to anyone using Fyne for their first app by logging text ;)

Checklist:

  • Tests included.
  • Lint and formatter run with no errors.
  • Tests all pass.
  • Public APIs match existing style and have Since: line.
package main

import (
	"strconv"
	"time"

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

func main() {
	a := app.New()
	w := a.NewWindow("Hello")

	tg := widget.NewTextGrid()
	tg.ShowLineNumbers = true
	tg.Scroll = container.ScrollBoth
	w.SetContent(tg)
	w.Resize(fyne.NewSize(120, 100))

	go func() {
		i := 0
		for {
			time.Sleep(time.Millisecond * 25)
			fyne.Do(func() {
				tg.Append("Another line added, this time it's..." + strconv.Itoa(i))
				i++
			})
		}
	}()
	w.ShowAndRun()
}

@coveralls
Copy link

coveralls commented Jan 19, 2025

Coverage Status

coverage: 59.122% (+0.08%) from 59.043%
when pulling 61ca852 on andydotxyz:feature/scrolltextgrid
into 351aebe on fyne-io:develop.

Copy link
Member

@Jacalz Jacalz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. This is a really nice change. I left a few suggestions and a comment about a potential bug I found. Would it not be nice to also update fyne_demo so this can be showcased in some way?

t.scroll.Hide()
t.scroll.Content = nil
content.Resize(t.text.Size())
t.SetObjects([]fyne.CanvasObject{t.text})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be faster and potentially even cleaner, to do just not use a base renderer (or expose its internal object slice) to just set t.objects[0] = t.text.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've honestly thought about removing that helper sometimes. It rarely adds much in my opinion and many renderers don't even use it.


t.scroll.Resize(t.text.Size())
content.Resize(content.MinSize())
t.SetObjects([]fyne.CanvasObject{t.scroll})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above.

Comment on lines 527 to 531
var toRemove []*textGridRow
for _, row := range t.visible {
if row.(*textGridRow).row < start || row.(*textGridRow).row > end {
toRemove = append(toRemove, row.(*textGridRow))
break
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like toRemove is only ever going to be of length one? Seems strange.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch

x := 0
if t.obj.row >= len(t.obj.text.text.Rows) {
return // empty?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The question mark in the comment makes me worried. Is there something strange going on here? Are unsure about that the effect of returning here does?

widget/textgrid.go Show resolved Hide resolved
Comment on lines 388 to 391
if t.scroll.Content != nil {
t.scroll.Resize(s)
}
t.text.Resize(s)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the suggestion about accessing the objects slice below, this could be:

Suggested change
if t.scroll.Content != nil {
t.scroll.Resize(s)
}
t.text.Resize(s)
t.objects[0].Resize(s)

Comment on lines +304 to +317
var scroll *widget.Scroll
content := newTextGridContent(t)
objs := make([]fyne.CanvasObject, 1)
if t.Scroll == widget.ScrollNone {
scroll = widget.NewScroll(nil)
objs[0] = content
} else {
scroll = widget.NewScroll(content)
scroll.Direction = t.Scroll
objs[0] = scroll
}
t.scroll = scroll
r := &textGridRenderer{text: content, scroll: scroll}
r.SetObjects(objs)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be cleaned up a bit:

Suggested change
var scroll *widget.Scroll
content := newTextGridContent(t)
objs := make([]fyne.CanvasObject, 1)
if t.Scroll == widget.ScrollNone {
scroll = widget.NewScroll(nil)
objs[0] = content
} else {
scroll = widget.NewScroll(content)
scroll.Direction = t.Scroll
objs[0] = scroll
}
t.scroll = scroll
r := &textGridRenderer{text: content, scroll: scroll}
r.SetObjects(objs)
var inScroller fyne.CanvasObject
content := newTextGridContent(t)
objs := []fyne.CanvasObject{content}
if t.Scroll != widget.ScrollNone {
inScroller = content
scroll.Direction = t.Scroll
objs[0] = scroll
}
t.scroll = widget.NewScroll(inScroller)
r := &textGridRenderer{text: content, scroll: t.scroll}
r.SetObjects(objs)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels subjective - can it be definitive that creating "inScroller" to avoid an else is better?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yeah. Might be subjective. I just try to avoid branches as much as possible because it is less code indented to the right. Do as you wish :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that but it is not removing an indent (as that level deep was already there).
I was a little confused because the nil content of Scroller becomes implicit which could look like a bug.

@andydotxyz
Copy link
Member Author

Would it not be nice to also update fyne_demo so this can be showcased in some way?

I didn't bother with the fyne_demo because, as you saw in another PR, I'm hoping to replace the tutorials with our new code style assisting demo.

@andydotxyz
Copy link
Member Author

I've addressed what I think are the objective fixes. The other items are commenting on pre-existing algorithms or are suggestions about how the code could be - but I think we should stick to what needs to be better for a clear reason TBH.

@Jacalz
Copy link
Member

Jacalz commented Jan 23, 2025

Sorry if it wasn't clear but I basically tried to give suggestions and so on as well. I think your points are fair :)

@andydotxyz andydotxyz merged commit f8dfaaa into fyne-io:develop Jan 24, 2025
12 checks passed
@andydotxyz andydotxyz deleted the feature/scrolltextgrid branch January 24, 2025 09:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants