fyne-io / fyne

Cross platform GUI toolkit in Go inspired by Material Design
https://fyne.io/
Other
24.73k stars 1.37k forks source link

Accordion Event on Open/Close #1493

Open Stoyvo opened 3 years ago

Stoyvo commented 3 years ago

Is your feature request related to a problem? Please describe:

Layouts resize based on accordion open and closing. I would expect a layout to return to the size it was previously before accordion item opened (Maybe a feature in the future), however this can be achieved with events on accordion open and close.

Is it possible to construct a solution with the existing API?

I do not believe it's possible to perform on existing API.

Describe the solution you'd like to see:

Similar to Check widget, implement an OnChange and boolean of opened.

andydotxyz commented 3 years ago

The layouts should be collapsing when the accordion closes. Can you please share a code snippet and maybe screenshot that shows the issue so we can replicate locally?

andydotxyz commented 3 years ago

I'm not sure that a callback with a simple bool would solve the issue as Accordion can contain many AccordionItems.

Stoyvo commented 3 years ago

Hi @andydotxyz - I have written a small app that demonstrates this issue. Unless I've missed it many times, I dont see a way to resolve this window resize:

package main

import (
    "fyne.io/fyne"
    "fyne.io/fyne/app"
    "fyne.io/fyne/canvas"
    "fyne.io/fyne/container"
    "fyne.io/fyne/layout"
    "fyne.io/fyne/widget"
)

var App fyne.App
var Window fyne.Window
var art *canvas.Image
var last *widget.Label

func main() {
    App = app.NewWithID("com.example.fyne1493")
    Window = App.NewWindow("Resize Example")
    header := buildHeader()

    art = &canvas.Image{FillMode: canvas.ImageFillOriginal}
    art.SetMinSize(fyne.Size{Width: 120, Height: 120})
    art.Show()

    last = widget.NewLabel("Click on settings, window will resize, but closing settings window remains same size.")
    last.Wrapping = fyne.TextWrapWord
    last.Alignment = fyne.TextAlignCenter

    mainContent := fyne.NewContainerWithLayout(
        layout.NewCenterLayout(),
        container.NewVBox(
            buildDetails(),
        ),
    )

    settings := buildSettings()

    Window.SetContent(fyne.NewContainerWithLayout(
        layout.NewBorderLayout(header, settings, nil, nil),
        header,
        settings,
        mainContent,
    ))
    Window.Resize(fyne.Size{Width: 400, Height: 320})

    Window.CenterOnScreen()

    Window.ShowAndRun()
}

func buildHeader() *fyne.Container {
    logo := canvas.NewImageFromFile("test.jpg")
    logo.FillMode = canvas.ImageFillOriginal
    appName := widget.NewLabelWithStyle(
        "FYNE-1493",
        fyne.TextAlignCenter,
        fyne.TextStyle{Bold: true},
    )
    headerLayout := fyne.NewContainerWithLayout(
        layout.NewVBoxLayout(),
        logo,
        appName,
    )

    return headerLayout
}

func buildDetails() *fyne.Container {
    details := container.NewVBox(
        last,
        art,
    )

    return fyne.NewContainerWithLayout(
        layout.NewVBoxLayout(),
        details,
    )
}

func buildSettings() *fyne.Container {
    return fyne.NewContainerWithLayout(
        layout.NewCenterLayout(),
        widget.NewAccordion(
            widget.NewAccordionItem(
                "Settings",
                container.NewAppTabs(
                    buildTrackTab(),
                    buildStreamTab(),
                ),
            ),
        ),
    )
}

func buildTrackTab() *container.TabItem {
    // Remove ( ) Brackets
    removeRoundBrackets := widget.NewCheck("Remove ( ) Brackets", nil)
    removeRoundBrackets.SetChecked(App.Preferences().BoolWithFallback("remove_round_brackets", true))

    // Remove [ ] Brackets
    removeSquareBrackets := widget.NewCheck("Remove [ ] Brackets", nil)
    removeSquareBrackets.SetChecked(App.Preferences().BoolWithFallback("remove_square_brackets", true))

    // Remove { } Brackets
    removeBraceBrackets := widget.NewCheck("Remove { } Brackets", nil)
    removeBraceBrackets.SetChecked(App.Preferences().BoolWithFallback("remove_brace_brackets", true))

    // Remove < > Arrows
    removeArrowBrackets := widget.NewCheck("Remove < > Arrows", nil)
    removeArrowBrackets.SetChecked(App.Preferences().BoolWithFallback("remove_arrow_brackets", true))

    return container.NewTabItem(
        "Track Display",
        fyne.NewContainerWithLayout(layout.NewVBoxLayout(),
            container.NewVBox(
                removeRoundBrackets,
                removeSquareBrackets,
                removeBraceBrackets,
                removeArrowBrackets,
            ),
        ),
    )
}

func buildStreamTab() *container.TabItem {
    // Enable/Disable Chat Bot
    enableChatBot := widget.NewCheck("Enable", nil)
    enableChatBot.SetChecked(App.Preferences().BoolWithFallback("enable_chat_bot", true))

    // Stream Font Family
    streamFont := widget.NewEntry()
    streamFont.PlaceHolder = "Font Family"

    // Stream Font Size
    streamFontSize := widget.NewSelect(
        []string{"16", "20","24"},
        nil,
    )
    streamFontSize.PlaceHolder = "Font Size"
    streamFontSize.SetSelected(App.Preferences().String("stream_font_size"))

    // Stream Font Color
    streamFontColor := widget.NewEntry()
    streamFontColor.Text = App.Preferences().StringWithFallback("stream_font_color", "#FFFFFF")

    return container.NewTabItem(
        "Fonts",
        fyne.NewContainerWithLayout(layout.NewVBoxLayout(),
            container.NewVBox(
                enableChatBot,
                streamFont,
                streamFontSize,
                streamFontColor,
            ),
        ),
    )
}
Stoyvo commented 3 years ago

I'm not sure that a callback with a simple bool would solve the issue as Accordion can contain many AccordionItems.

True, however an event observation on the AccorionItem open or close would be useful. I do believe this should be a feature request and tracked in another ticket, and the issue with resize is a bug?

andydotxyz commented 3 years ago

Unless I've missed it many times, I dont see a way to resolve this window resize:

Oh you meant the window is not resizing, I thought you were referring to container layouts. This is correct. Once a window becomes larger due to the content inside it requiring this space it will not automatically shrink again. This is by design. Imagine how annoying it would be if your window changed size with each tab you selected in a tab container.

I do believe this should be a feature request and tracked in another ticket, and the issue with resize is a bug?

Happy for this issue to track the feature request, as you list in the title. The bug you describe is functioning correctly.

Stoyvo commented 3 years ago

This is by design. Imagine how annoying it would be if your window changed size with each tab you selected in a tab container.

Agreed, it would be annoying, and the use of an accordion to show/hide settings is not a great design decision if we want the window size to remain the same size. With the addition of an event on open/close of accordion item, the ability to programatically resize the window becomes possible.

Thank you for considering the enhancement! You and all contributors efforts are greatly appreciated.

andydotxyz commented 3 years ago

Thanks :) we have a great team here indeed. I'll add this to our general bufix milestone and see if we can get something sorted