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

Add table widget #157

Closed
andydotxyz opened this issue Mar 19, 2019 · 12 comments
Closed

Add table widget #157

andydotxyz opened this issue Mar 19, 2019 · 12 comments
Labels
Design Requires some visual design process

Comments

@andydotxyz
Copy link
Member

For showing data elegantly.

This will require #135 to do properly

@andydotxyz andydotxyz added the future Features that might take a while to be sheduled label Mar 19, 2019
@warmans
Copy link

warmans commented Mar 26, 2019

For anyone trying to do this - you can make a reasonable facsimile of a table using a grid layout (example attached).

Not sure how to add borders and stuff though.

package main

import (
	"fyne.io/fyne"
	"fyne.io/fyne/app"
	"fyne.io/fyne/layout"
	"fyne.io/fyne/theme"
	"fyne.io/fyne/widget"
)

func main() {
	app := app.New()

	w := app.NewWindow("Hello")

	w.SetContent(
		widget.NewVBox(
			makeTable(
				[]string{"Foo", "Bar", "Baz"},
				[][]string{{"1", "2", "3"}, {"4", "5", "6"}},
			),
		),
	)
	w.ShowAndRun()
}

func makeTable(headings []string, rows [][]string) *widget.Box {

	columns := rowsToColumns(headings, rows)

	objects := make([]fyne.CanvasObject, len(columns))
	for k, col := range columns {
		box := widget.NewVBox(widget.NewLabelWithStyle(headings[k], fyne.TextAlignLeading, fyne.TextStyle{Bold: true}))
		for _, val := range col {
			box.Append(widget.NewLabel(val))
		}
		objects[k] = box
	}
	return widget.NewVBox(
		fyne.NewContainerWithLayout(layout.NewGridLayout(len(columns)), objects...),
	)
}


func rowsToColumns(headings []string, rows [][]string) [][]string {
	columns := make([][]string, len(headings))
	for _, row := range rows {
		for colK := range row {
			columns[colK] = append(columns[colK], row[colK])
		}
	}
	return columns
} 

@andydotxyz andydotxyz added the Design Requires some visual design process label Apr 9, 2019
@Kvaz1r
Copy link
Contributor

Kvaz1r commented Apr 11, 2019

Yeah grid control definitely useful. Code above is great for static tables but really often one need sortable by column.

@andydotxyz andydotxyz added this to the Release 1.2 milestone Jun 15, 2019
@andydotxyz andydotxyz removed the future Features that might take a while to be sheduled label Jun 15, 2019
@steveoc64
Copy link
Member

subbed

@andydotxyz
Copy link
Member Author

Having noticed that the above does not do quite what I thought I have mocked up a version that allows the columns to fit to their content instead:

package main

import (
	"fyne.io/fyne"
	"fyne.io/fyne/app"
	"fyne.io/fyne/widget"
)

func main() {
	app := app.New()

	w := app.NewWindow("Hello")

	w.SetContent(
		makeTable(
			[]string{"Foo is much longer", "Bar", "Baz"},
			[][]string{{"1", "2", "3"}, {"4", "5", "6"}},
		),
	)
	w.ShowAndRun()
}

func makeTable(headings []string, rows [][]string) *widget.Box {

	columns := rowsToColumns(headings, rows)

	objects := make([]fyne.CanvasObject, len(columns))
	for k, col := range columns {
		box := widget.NewVBox(widget.NewLabelWithStyle(headings[k], fyne.TextAlignLeading, fyne.TextStyle{Bold: true}))
		for _, val := range col {
			box.Append(widget.NewLabel(val))
		}
		objects[k] = box
	}
	return widget.NewHBox(objects...)
}


func rowsToColumns(headings []string, rows [][]string) [][]string {
	columns := make([][]string, len(headings))
	for _, row := range rows {
		for colK := range row {
			columns[colK] = append(columns[colK], row[colK])
		}
	}
	return columns
} 

@rfay
Copy link

rfay commented Mar 10, 2020

To build this updated example you need to do some vendor magic or you may get failures like "fatal error: 'glfw/src/context.c' file not found' as in icexin/gocraft#8. Those can be fixed using the hacky technique there (icexin/gocraft#8 (comment)), but it's probably easier and perhaps more repeatable to use the new in-development fyne vendor command to update the vendor dir.

git clone github.com/fyne-io/fyne
cd fyne
git checkout origin/develop
go install ./cmd/fyne
cd <myproject>
~/go/bin/fyne vendor
go run main.go

@rfay
Copy link

rfay commented Mar 10, 2020

@andydotxyz could you edit the title to mention "tables with columns of appropriate width", thanks.

@andydotxyz
Copy link
Member Author

Hmm, it seems a bit specific. the table view will have a list of requirements or functionality, the initial description, though short (For showing data elegantly) I think captures that and many more ;)

@rfay
Copy link

rfay commented Mar 11, 2020

I was actually just asking for a title that would have led me to this when searching the issues before opening #737 . It's a very common need to have auto-sizing on columns, and people will want it, even if they have to do it this way. But they won't find it with this title. Thanks for all your help.

@andydotxyz
Copy link
Member Author

This ticket will now turn up in results because it was discussed - the content is matched and highlighted in results.

@charlesdaniels
Copy link
Member

It might be worth considering a data frame library such as gota. This gives us sorting, filtering, easy import/export to disk, and support for different types of data values. I was going to put this in #135, but I think maybe this idea fits better here since to the extent I understand MVVM this doesn't fully solve that problem.

My thought would be that perhaps the table could track what canvas objects are associated with which cells in the dataframe. When it needs to refresh, it can easily determine if it needs to create new objects or update existing ones in place.

It would be nice to include a locking mechanism, to ensure the user isn't modifying the data at the same time as it's being read for an update. Possibly we could either find a dataframe library that supports locking, write our own (possibly forking one) or add it upstream.

@charlesdaniels
Copy link
Member

Prior art: I've used tksheet before with tkinter in Python, and by and large I think it gets things right.

@andydotxyz
Copy link
Member Author

On develop for testing :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Requires some visual design process
Projects
None yet
Development

No branches or pull requests

6 participants