gofyne

Golang Fyne, Limit the size of the left object with NewHSplit


enter image description here

enter image description here

example1 gif

example2 gif

I'm trying to create a navigation bar on the left side of the window. The problem is that the line (NewHSplit) can be moved to the left, thereby overlapping the content on the left side. I would like to set the minimum width of the navigation bar, but I don't understand how to do it correctly.

Before that, I tried using a container.NewAppTabs(), but this solution is not suitable, because the elements inside the container do not support alignment (the text is positioned in the center, but I need it on the left). I also tried using nav := container.New(layout.NewGridWrapLayout(fyne.Size{Width: 100}), components.NavigationBar()), which partially solved the problem, but now the navigation bar elements are not displayed (see examaple2 gif)

var data = []string{"Profile", "Messenger"}

// package components
func NavigationBar() *widget.List {
    nav := &widget.List{}
    nav.Length = func() int {
        return len(data)
    }
    nav.OnSelected = func(id widget.ListItemID) {
        fmt.Printf("Selected: %s\n", data[id])
    }
    nav.CreateItem = func() fyne.CanvasObject {
        l := widget.NewLabel("")
        return l
    }
    nav.UpdateItem = func(id widget.ListItemID, item fyne.CanvasObject) {
        item.(*widget.Label).SetText(data[id])
    }
    return nav
}

// package windows
func MasterWindow(a fyne.App, hide bool) fyne.Window {
    w := a.NewWindow("SAC-Client")
    w.SetMaster()
    w.CenterOnScreen()
    w.Resize(fyne.NewSize(1000, 600))
    if hide == true {
        w.Hide()
    } else {
        w.Show()
    }
    return w
}

func main() {
    a := app.NewWithID("sac-client")
    w := windows.MasterWindow(a, false)
    nav := container.New(layout.NewStackLayout(), components.NavigationBar())
    nav.Resize(fyne.Size{Width: 100})
    nav.Refresh()
    label := container.NewHBox(widget.NewLabel("Test Label"))
    c := container.NewHSplit(nav, label)
    c.Offset = 0.1
    w.SetContent(c)
    a.Run()
}

UPD: The final solution

var data = []string{"Profile", "Messenger"}

func findMax(values []string) string {
    lastValue := ""
    for _, v := range values {
        if len(v) > len(lastValue) {
            lastValue = v
        }
    }
    return lastValue
}

func NavigationBar() *widget.List {
    nav := &widget.List{}
    maxValue := findMax(data)
    nav.Length = func() int {
        return len(data)
    }
    nav.OnSelected = func(id widget.ListItemID) {
        fmt.Printf("Selected: %s\n", data[id])
    }
    nav.CreateItem = func() fyne.CanvasObject {
        l := widget.NewLabel(maxValue)
        return l
    }
    nav.UpdateItem = func(id widget.ListItemID, item fyne.CanvasObject) {
        item.(*widget.Label).SetText(data[id])
    }
    return nav
}

Solution

  • The minimum size of an item in a split is, like all other components, determined by the result of its MinSize() method.

    The probably appears to be that you have configured the navigation list to use “” as the default label width. Use template content that is actually indicative of the items you want to hold space for.