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

Button/toolbar weird flickering inside table #3685

Closed
2 tasks done
UrbiJr opened this issue Feb 27, 2023 · 5 comments
Closed
2 tasks done

Button/toolbar weird flickering inside table #3685

UrbiJr opened this issue Feb 27, 2023 · 5 comments
Labels
unverified A bug that has been reported but not verified

Comments

@UrbiJr
Copy link

UrbiJr commented Feb 27, 2023

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

When putting either a *widget.Toolbar or a *widget.Button inside a *widget.Table cell, it makes a weird flickering whenever you put the cursor on that cell.
Putting the cursor in a certain position will also cause different effects depending on the position: the toolbar for example would display its icons partially if putting the cursor above the first icon, instead putting it above the last (third) icon always displays the toolbar correctly.

How to reproduce

  • Create a widget.Table using widget.NewTable
  • Inside the update func(TableCellID, fyne.CanvasObject) body, put the code to insert either a *widget.Toolbar or a *widget.Button in a cell
  • Display the table and run the program

Screenshots

fyneflicker

Example code

func (app *Config) getProfilesTable() *widget.Table {
	t := widget.NewTable(
		func() (int, int) {
			return len(app.ProfilesSlice), len(app.ProfilesSlice[0])
		},
		func() fyne.CanvasObject {
			ctr := container.NewVBox(widget.NewLabel(""))
			ctr.Resize(fyne.Size{Height: 50})
			return ctr
		},
		func(tci widget.TableCellID, co fyne.CanvasObject) {
			// in order: if last column && not the first row
			if tci.Col == (len(app.ProfilesSlice[0])-1) && tci.Row != 0 {
				w := widget.NewToolbar(
					widget.NewToolbarAction(theme.ContentCopyIcon(), func() {}),
					widget.NewToolbarAction(theme.DocumentCreateIcon(), func() {}),
					widget.NewToolbarAction(theme.DeleteIcon(), func() {}))

				co.(*fyne.Container).Objects = []fyne.CanvasObject{w}
			} else {
				// we're just putting in textual information
				co.(*fyne.Container).Objects = []fyne.CanvasObject{
					widget.NewLabel(app.ProfilesSlice[tci.Row][tci.Col].(string)),
				}
			}
		})

	colWidths := []float32{100, 200, 200, 200, 60}
	for i, w := range colWidths {
		t.SetColumnWidth(i, w)
	}

	for i := 1; i < len(app.ProfilesSlice); i++ {
		t.SetRowHeight(i, 55)
	}

	return t
}

Fyne version

2.3.1

Go compiler version

go1.19.1 windows/amd64 / go1.19.1 darwin/arm64

Operating system and version

Windows 11 / macOS Monterey

Additional Information

I would like to add, I'm extremely grateful for your work! Fyne is really extraordinary and I can't wait to finish my application. Thank you!

@UrbiJr UrbiJr added the unverified A bug that has been reported but not verified label Feb 27, 2023
@andydotxyz
Copy link
Member

Do not create new content in the Update callback - this is where you should configure components that were created in the Create callback.
You can hide and show but creating new items will not give the desired result.

@junmaqiang

This comment was marked as off-topic.

@junmaqiang
Copy link

Do not create new content in the Update callback - this is where you should configure components that were created in the Create callback. You can hide and show but creating new items will not give the desired result.

I think Official lack of trial examples to guide

@andydotxyz
Copy link
Member

What I described is documented at https://developer.fyne.io/widget/table

@UrbiJr
Copy link
Author

UrbiJr commented Mar 23, 2023

hey there, sorry if I hadn't replied sooner, but just got busy with other work.
I solved looking at the example @andydotxyz mentioned, and also thanks to a SO question.

If anyone needs, this is how I put a toolbar and other objects inside a table (not it won't flicker anymore 😁):

package main

import (
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
)

var data = [][]string{[]string{"label", "actions"},
	[]string{"hello", "toolbar goes here"}}

func main() {
	myApp := app.New()
	myWindow := myApp.NewWindow("Table Widget")

	list := widget.NewTable(
		func() (int, int) {
			return len(data), len(data[0])
		},
		func() fyne.CanvasObject {
			lbl := widget.NewLabel("")
			toolbar := widget.NewToolbar()
			toolbar.Hide()
			return container.NewMax(lbl, toolbar)
		},
		func(i widget.TableCellID, o fyne.CanvasObject) {
			container := o.(*fyne.Container)
			lbl := container.Objects[0].(*widget.Label)
			toolbar := container.Objects[1].(*widget.Toolbar)

			if i.Row != 0 && i.Col == 1 {
				lbl.Hide()
				toolbar.Hidden = false

				if len(toolbar.Items) == 0 {
					toolbar.Append(widget.NewToolbarAction(theme.ContentCopyIcon(), func() {}))
					toolbar.Append(widget.NewToolbarAction(theme.DocumentCreateIcon(), func() {}))
					toolbar.Append(widget.NewToolbarAction(theme.DeleteIcon(), func() {}))
				}

			} else {
				toolbar.Hide()
				lbl.Hidden = false
				lbl.SetText(data[i.Row][i.Col])
			}
		})

	// hide first column (ID)
	colWidths := []float32{100, 100}
	for i, w := range colWidths {
		list.SetColumnWidth(i, w)
	}

	myWindow.SetContent(list)
	myWindow.ShowAndRun()
}

@UrbiJr UrbiJr closed this as completed Mar 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
unverified A bug that has been reported but not verified
Projects
None yet
Development

No branches or pull requests

3 participants