Maison > développement back-end > Golang > le corps du texte

Personnaliser la disposition de la grille adaptative Fyne

PHPz
Libérer: 2024-02-12 15:30:07
avant
877 Les gens l'ont consulté

自定义 Fyne 自适应网格布局

Contenu de la question

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()
}
Copier après la connexion

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.

Solution

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()
}
Copier après la connexion

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!

source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!