Maison > Article > développement back-end > Personnaliser la disposition de la grille adaptative Fyne
Je modifie le conteneur.newadaptivegrid() de la bibliothèque fyne pour restituer la largeur du widget en fonction des tranches proportionnelles que nous passons. À partir de maintenant, containers.newadaptivegrid() restitue des widgets de largeur égale dans une rangée. Fondamentalement (taille totale des lignes / widgets maintenant).
Mon code :
package main import ( "fmt" "math" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" ) func New(layout fyne.Layout, objects ...fyne.CanvasObject) *fyne.Container { return fyne.NewContainerWithLayout(layout, objects...) } func NewAdaptiveGridWithRatios(ratios []float32, objects ...fyne.CanvasObject) *fyne.Container { return New(NewAdaptiveGridLayoutWithRatios(ratios), objects...) } // Declare conformity with Layout interface var _ fyne.Layout = (*adaptiveGridLayoutWithRatios)(nil) type adaptiveGridLayoutWithRatios struct { ratios []float32 adapt, vertical bool } func NewAdaptiveGridLayoutWithRatios(ratios []float32) fyne.Layout { return &adaptiveGridLayoutWithRatios{ratios: ratios, adapt: true} } func (g *adaptiveGridLayoutWithRatios) horizontal() bool { if g.adapt { return fyne.IsHorizontal(fyne.CurrentDevice().Orientation()) } return !g.vertical } func (g *adaptiveGridLayoutWithRatios) countRows(objects []fyne.CanvasObject) int { count := 0 for _, child := range objects { if child.Visible() { count++ } } return int(math.Ceil(float64(count) / float64(len(g.ratios)))) } // Get the leading (top or left) edge of a grid cell. // size is the ideal cell size and the offset is which col or row its on. func getLeading(size float64, offset int) float32 { ret := (size + float64(theme.Padding())) * float64(offset) return float32(ret) } // Get the trailing (bottom or right) edge of a grid cell. // size is the ideal cell size and the offset is which col or row its on. func getTrailing(size float64, offset int) float32 { return getLeading(size, offset+1) - theme.Padding() } // Layout is called to pack all child objects into a specified size. // For a GridLayout this will pack objects into a table format with the number // of columns specified in our constructor. func (g *adaptiveGridLayoutWithRatios) Layout(objects []fyne.CanvasObject, size fyne.Size) { rows := g.countRows(objects) cols := len(g.ratios) if g.horizontal() { cols = rows rows = len(g.ratios) } padWidth := float32(cols-1) * theme.Padding() padHeight := float32(rows-1) * theme.Padding() var totalRatio float32 for _, r := range g.ratios { totalRatio += r } cellWidth := (float64(size.Width) - float64(padWidth)) / float64(len(g.ratios)) cellHeight := float64(size.Height-padHeight) / float64(rows) if !g.horizontal() { cellWidth, cellHeight = cellHeight, cellWidth cellWidth = float64(size.Width-padWidth) / float64(rows) cellHeight = float64(size.Height-padHeight) / float64(len(g.ratios)) } row, col := 0, 0 i := 0 for _, child := range objects { if !child.Visible() { continue } //ratio := g.ratios[j%len(g.ratios)] cellSize := fyne.NewSize(float32(cellWidth)*g.ratios[i], float32(cellHeight)) x1 := getLeading(float64(cellSize.Width), col) y1 := getLeading(float64(cellSize.Height), row) x2 := getTrailing(float64(cellSize.Width), col) y2 := getTrailing(float64(cellSize.Height), row) fmt.Println("1s :", x1, y1) fmt.Println("2s :", x2, y2) child.Move(fyne.NewPos(x1, y1)) child.Resize(cellSize) if g.horizontal() { if (i+1)%cols == 0 { row++ col = 0 } else { col++ } } else { if (i+1)%cols == 0 { col++ row = 0 } else { row++ } } i++ } fmt.Println("i :", i) } func (g *adaptiveGridLayoutWithRatios) MinSize(objects []fyne.CanvasObject) fyne.Size { minSize := fyne.NewSize(0, 0) return minSize } func main() { myApp := app.New() myWindow := myApp.NewWindow("My Windows") myWindow.Resize(fyne.NewSize(600, 200)) button1 := widget.NewButton("Button 1", func() { // Handle button click for button 1 }) button2 := widget.NewButton("Button 2", func() { // Handle button click for button 2 }) button1.Importance = widget.WarningImportance button2.Importance = widget.DangerImportance title := widget.NewLabelWithStyle("Custom", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}) myWindow.SetContent(container.NewVBox(title, NewAdaptiveGridWithRatios([]float32{0.3, 0.7}, button1, button2))) myWindow.ShowAndRun() }
Je souhaite que les boutons soient placés côte à côte avec un rapport de largeur relative de 3:7. Mais j'obtiens deux lignes horizontales, l'une en dessous de l'autre. Je modifie : https://github.com/fyne-io/fyne/blob/8c2509518b2df442a6b748d9b07754739592e6d7/layout/gridlayout.go Fabriquer mes produits personnalisés.
Cela fonctionne :
package main import ( "fmt" "math" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" ) func New(layout fyne.Layout, objects ...fyne.CanvasObject) *fyne.Container { return fyne.NewContainerWithLayout(layout, objects...) } func NewAdaptiveGridWithRatios(ratios []float32, objects ...fyne.CanvasObject) *fyne.Container { return New(NewAdaptiveGridLayoutWithRatios(ratios), objects...) } // Declare conformity with Layout interface var _ fyne.Layout = (*adaptiveGridLayoutWithRatios)(nil) type adaptiveGridLayoutWithRatios struct { ratios []float32 adapt, vertical bool } func NewAdaptiveGridLayoutWithRatios(ratios []float32) fyne.Layout { return &adaptiveGridLayoutWithRatios{ratios: ratios, adapt: true} } func (g *adaptiveGridLayoutWithRatios) horizontal() bool { if g.adapt { return fyne.IsHorizontal(fyne.CurrentDevice().Orientation()) } return !g.vertical } func (g *adaptiveGridLayoutWithRatios) countRows(objects []fyne.CanvasObject) int { count := 0 for _, child := range objects { if child.Visible() { count++ } } return int(math.Ceil(float64(count) / float64(len(g.ratios)))) } // Layout is called to pack all child objects into a specified size. // For a GridLayout this will pack objects into a table format with the number // of columns specified in our constructor. func (g *adaptiveGridLayoutWithRatios) Layout(objects []fyne.CanvasObject, size fyne.Size) { rows := g.countRows(objects) cols := len(g.ratios) padWidth := float32(cols-1) * theme.Padding() padHeight := float32(rows-1) * theme.Padding() tGap := float64(padWidth) tcellWidth := float64(size.Width) - tGap cellHeight := float64(size.Height-padHeight) / float64(rows) fmt.Println(cols, rows) fmt.Println(cellHeight, tcellWidth+tGap, tGap) fmt.Println("tcellWidth, cellHeight", tcellWidth, cellHeight) if !g.horizontal() { padWidth, padHeight = padHeight, padWidth tcellWidth = float64(size.Width-padWidth) - tGap cellHeight = float64(size.Height-padHeight) / float64(cols) } row, col := 0, 0 i := 0 var x1, x2, y1, y2 float32 = 0.0, 0.0, 0.0, 0.0 fmt.Println("padWidth, padHeight, tcellWidth, cellHeight, float32(theme.Padding()):", padWidth, padHeight, tcellWidth, cellHeight, float32(theme.Padding())) for _, child := range objects { if !child.Visible() { continue } if i == 0 { x1 = 0 y1 = 0 } else { x1 = x2 + float32(theme.Padding())*float32(1) y1 = y2 - float32(cellHeight) } // float32(tGap/float64(col)) // (size + float64(theme.Padding())) * float64(offset) float32(theme.Padding())*float32(1) x2 = x1 + float32(tcellWidth*float64(g.ratios[i])) y2 = float32(cellHeight) fmt.Println("x1,y1 :", x1, y1) fmt.Println("x2, y2 :", x2, y2) fmt.Println("eff width", tcellWidth*float64(g.ratios[i])) fmt.Println("------") child.Move(fyne.NewPos(x1, y1)) child.Resize(fyne.NewSize((x2 - x1), y2-y1)) if g.horizontal() { if (i+1)%cols == 0 { row++ col = 0 } else { col++ } } else { if (i+1)%cols == 0 { col++ row = 0 } else { row++ } } i++ } fmt.Println("i :", i) } func (g *adaptiveGridLayoutWithRatios) MinSize(objects []fyne.CanvasObject) fyne.Size { rows := g.countRows(objects) minSize := fyne.NewSize(0, 0) for _, child := range objects { if !child.Visible() { continue } minSize = minSize.Max(child.MinSize()) } if g.horizontal() { minContentSize := fyne.NewSize(minSize.Width*float32(len(g.ratios)), minSize.Height*float32(rows)) return minContentSize.Add(fyne.NewSize(theme.Padding()*fyne.Max(float32(len(g.ratios)-1), 0), theme.Padding()*fyne.Max(float32(rows-1), 0))) } minContentSize := fyne.NewSize(minSize.Width*float32(rows), minSize.Height*float32(len(g.ratios))) return minContentSize.Add(fyne.NewSize(theme.Padding()*fyne.Max(float32(rows-1), 0), theme.Padding()*fyne.Max(float32(len(g.ratios)-1), 0))) } func main() { myApp := app.New() myWindow := myApp.NewWindow("My Windows Custom UI") myWindow.Resize(fyne.NewSize(600, 200)) var buttons [16]*widget.Button for i := 0; i < 16; i++ { button := widget.NewButton(fmt.Sprintf("Btn %d", i+1), func() { // Handle button click for this button }) // Set the button importance based on the button index if i%2 == 0 { button.Importance = widget.WarningImportance } else { button.Importance = widget.DangerImportance } buttons[i] = button } pgBar := widget.NewLabelWithStyle("Progress :", fyne.TextAlignCenter, fyne.TextStyle{Italic: true}) progressBar := widget.NewProgressBar() progressBar.SetValue(0.95) myWindow.SetContent(container.NewVBox( NewAdaptiveGridWithRatios([]float32{0.1, 0.4, 0.4, 0.1}, buttons[0], buttons[1], buttons[2], buttons[3]), NewAdaptiveGridWithRatios([]float32{0.2, 0.3, 0.1, 0.4}, buttons[4], buttons[5], buttons[6], buttons[7]), NewAdaptiveGridWithRatios([]float32{0.6, 0.1, 0.2, 0.1}, buttons[8], buttons[9], buttons[10], buttons[11]), NewAdaptiveGridWithRatios([]float32{0.1, 0.4, 0.4, 0.1}, buttons[12], buttons[13], buttons[14], buttons[15]), NewAdaptiveGridWithRatios([]float32{0.1, 0.9}, pgBar, progressBar), )) myWindow.ShowAndRun() }
J'ai ajouté plusieurs boutons et autres widgets dans des proportions différentes.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!