我正在修改fyne库的container.newadaptivegrid(),以便根据我们传递的比例切片渲染小部件的宽度。截至目前,container.newadaptivegrid() 在一行中呈现等宽的小部件。基本上(总行大小/现在的小部件)。
我的代码:
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() }
我希望按钮并排放置,按钮的相对宽度比例为 3:7。但我得到了两条水平线,一条在另一条之下。 我正在修改:https://github.com/fyne-io/fyne/blob/8c2509518b2df442a6b748d9b07754739592e6d7/layout/gridlayout.go 制作我的定制产品。
这有效:
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() }
以上是自定义 Fyne 自适应网格布局的详细内容。更多信息请关注PHP中文网其他相关文章!