Heim >Backend-Entwicklung >Golang >Passen Sie das adaptive Rasterlayout von Fyne an
Ich ändere den Container.newadaptivegrid() der Fyne-Bibliothek, um die Breite des gerenderten Widgets basierend auf dem Verhältnis, das wir ihm übergeben, aufzuteilen. Ab sofort rendert container.newadaptivegrid() Widgets gleicher Breite in einer Reihe. Grundsätzlich (jetzt Gesamtzeilengröße/Widgets).
Mein 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() }
Ich möchte, dass die Schaltflächen nebeneinander mit einem relativen Breitenverhältnis von 3:7 platziert werden. Aber ich bekomme zwei horizontale Linien, eine unter der anderen. Ich ändere: https://github.com/fyne-io/fyne/blob/8c2509518b2df442a6b748d9b07754739592e6d7/layout/gridlayout.go Stellen Sie meine individuellen Produkte her.
Das funktioniert:
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() }
Ich habe mehrere Schaltflächen und andere Widgets in unterschiedlichen Proportionen hinzugefügt.
Das obige ist der detaillierte Inhalt vonPassen Sie das adaptive Rasterlayout von Fyne an. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!