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

List widget panic when refreshing after changing content through combobox changed. #1864

Closed
changsheng1239 opened this issue Jan 26, 2021 · 2 comments
Labels
blocker Items that would block a forthcoming release bug Something isn't working

Comments

@changsheng1239
Copy link

Describe the bug:

If I display the list with 20 items but did not scroll it at all, changed the value of list and refresh. the list will display 1 item successfully. Whereas if I display 20 items and scrolled down, change the value of list and refresh will panic immediately with that error stack.

To Reproduce:

Steps to reproduce the behaviour:

  1. Run the example code.
  2. Change combo box value to 20.
  3. Scroll down for a bit.
  4. Change combo box value to 1.
  5. panic.

If step 3 is ignored, it will run successfully.

Example code:

package main

import (
	"strconv"

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

func main() {
	myApp := app.New()
	myWindow := myApp.NewWindow("List example")

	userTab, _ := renderUsersTab(myWindow)

	tabs := container.NewAppTabs(
		container.NewTabItem("Users", userTab),
	)
	tabs.SetTabLocation(container.TabLocationTop)

	myWindow.SetContent(tabs)
	myWindow.CenterOnScreen()
	myWindow.Resize(fyne.Size{Width: 700, Height: 500})
	myWindow.ShowAndRun()
}

func renderUsersTab(w fyne.Window) (fyne.CanvasObject, error) {
	groups := []string{"1", "10", "20"}
	members := generateEmails(1)

	l := widget.NewList(func() int {
		return len(members)
	}, func() fyne.CanvasObject {
		return widget.NewLabel("PLACEHOLDERS@DOMAIN.COM")
	}, func(lii widget.ListItemID, co fyne.CanvasObject) {
		if lii >= len(members) {
			return
		}
		val := members[lii]
		label := co.(*widget.Label)
		label.SetText(val)
	})

	groupLabel := widget.NewLabel("Groups")
	groupCombo := widget.NewSelect(groups, func(value string) {
		num, _ := strconv.Atoi(value)
		members = generateEmails(num)
		l.Refresh()
	})

	grid := container.New(layout.NewFormLayout(), groupLabel, groupCombo)
	tab := container.New(layout.NewBorderLayout(grid, nil, nil, nil), grid, l)
	return tab, nil
}

func generateEmails(num int) []string {
	emails := []string{}

	for i := 0; i < num; i++ {
		emails = append(emails, "testuser"+strconv.Itoa(i)+"@gmail.com")
	}

	return emails
}

Device:

  • OS: Windows
  • Version: 10 Pro
  • Go version: go version go1.15.7 windows/amd64
  • Fyne version: 2.0.0
@changsheng1239 changsheng1239 added the bug Something isn't working label Jan 26, 2021
@changsheng1239
Copy link
Author

If I used widget.Entry instead of Select, it worked as expected.

package main

import (
	"strconv"

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

func main() {
	myApp := app.New()
	myWindow := myApp.NewWindow("List example")

	userTab, _ := renderUsersTab(myWindow)

	tabs := container.NewAppTabs(
		container.NewTabItem("Users", userTab),
	)
	tabs.SetTabLocation(container.TabLocationTop)

	myWindow.SetContent(tabs)
	myWindow.CenterOnScreen()
	myWindow.Resize(fyne.Size{Width: 700, Height: 500})
	myWindow.ShowAndRun()
}

func renderUsersTab(w fyne.Window) (fyne.CanvasObject, error) {
	members := generateEmails(1)

	l := widget.NewList(func() int {
		return len(members)
	}, func() fyne.CanvasObject {
		return widget.NewLabel("PLACEHOLDERS@DOMAIN.COM")
	}, func(lii widget.ListItemID, co fyne.CanvasObject) {
		if lii >= len(members) {
			return
		}
		val := members[lii]
		label := co.(*widget.Label)
		label.SetText(val)
	})

	groupLabel := widget.NewLabel("Groups")
	groupEntry := widget.NewEntry()
	groupEntry.OnChanged = func(s string) {
		num, _ := strconv.Atoi(s)
		members = generateEmails(num)
		l.Refresh()
	}

	grid := container.New(layout.NewFormLayout(), groupLabel, groupEntry)
	tab := container.New(layout.NewBorderLayout(grid, nil, nil, nil), grid, l)
	return tab, nil
}

func generateEmails(num int) []string {
	emails := []string{}

	for i := 0; i < num; i++ {
		emails = append(emails, "testuser"+strconv.Itoa(i)+"@gmail.com")
	}

	return emails
}

@andydotxyz andydotxyz added the blocker Items that would block a forthcoming release label Jan 26, 2021
andydotxyz added a commit that referenced this issue Feb 12, 2021
Fix widget.List layout when the items length is lower than the current visible ones, fixes #1864
@andydotxyz
Copy link
Member

Fix on develop and release/v2.0.x for testing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocker Items that would block a forthcoming release bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants