diff --git a/CHANGELOG.md b/CHANGELOG.md index 27411b5945..44249851f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ More detailed release notes can be found on the [releases page](https://github.c * Go 1.17 or later is now required. * Icons for macOS bundles are now padded and rounded, disable with "-use-raw-icon" * Focus handling for List/Tree/Table are now at the parent widget not child elements +* Accordion widget now fills available space - put it inside a `VBox` container for old behavior ## 2.3.5 - 6 June 2023 diff --git a/cmd/fyne_demo/tutorials/widget.go b/cmd/fyne_demo/tutorials/widget.go index 80c0cf6738..f1b91bf42a 100644 --- a/cmd/fyne_demo/tutorials/widget.go +++ b/cmd/fyne_demo/tutorials/widget.go @@ -50,6 +50,7 @@ func makeAccordionTab(_ fyne.Window) fyne.CanvasObject { Detail: widget.NewLabel("Three"), }, ) + ac.MultiOpen = true ac.Append(widget.NewAccordionItem("D", &widget.Entry{Text: "Four"})) return ac } diff --git a/widget/accordion.go b/widget/accordion.go index 10fb9ae1e1..20efba06ba 100644 --- a/widget/accordion.go +++ b/widget/accordion.go @@ -118,13 +118,33 @@ type accordionRenderer struct { } func (r *accordionRenderer) Layout(size fyne.Size) { - dividerOff := (theme.Padding() + theme.SeparatorThicknessSize()) / 2 + pad := theme.Padding() + dividerOff := (pad + theme.SeparatorThicknessSize()) / 2 x := float32(0) y := float32(0) + hasOpen := 0 + for i, ai := range r.container.Items { + h := r.headers[i] + min := h.MinSize().Height + y += min + + if ai.Open { + y += pad + hasOpen++ + } + if i < len(r.container.Items)-1 { + y += pad + } + } + + openSize := (size.Height - y) / float32(hasOpen) + y = 0 for i, ai := range r.container.Items { if i != 0 { div := r.dividers[i-1] - div.Move(fyne.NewPos(x, y-dividerOff)) + if i > 0 { + div.Move(fyne.NewPos(x, y-dividerOff)) + } div.Resize(fyne.NewSize(size.Width, theme.SeparatorThicknessSize())) } @@ -133,23 +153,24 @@ func (r *accordionRenderer) Layout(size fyne.Size) { min := h.MinSize().Height h.Resize(fyne.NewSize(size.Width, min)) y += min + if ai.Open { d := ai.Detail d.Move(fyne.NewPos(x, y)) - min := d.MinSize().Height - d.Resize(fyne.NewSize(size.Width, min)) - y += min + d.Resize(fyne.NewSize(size.Width, openSize)) + y += openSize } if i < len(r.container.Items)-1 { - y += theme.Padding() + y += pad } } } func (r *accordionRenderer) MinSize() (size fyne.Size) { + pad := theme.Padding() for i, ai := range r.container.Items { if i != 0 { - size.Height += theme.Padding() + size.Height += pad } min := r.headers[i].MinSize() size.Width = fyne.Max(size.Width, min.Width) @@ -158,7 +179,7 @@ func (r *accordionRenderer) MinSize() (size fyne.Size) { size.Width = fyne.Max(size.Width, min.Width) if ai.Open { size.Height += min.Height - size.Height += theme.Padding() + size.Height += pad } } return diff --git a/widget/accordion_test.go b/widget/accordion_test.go index ab56836103..68704071c3 100644 --- a/widget/accordion_test.go +++ b/widget/accordion_test.go @@ -208,7 +208,125 @@ func TestAccordion_Layout(t *testing.T) { } window := test.NewWindow(&fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{accordion}}) - window.Resize(accordion.MinSize().Max(fyne.NewSize(150, 200))) + window.Resize(accordion.MinSize().Add(fyne.NewSquareSize(theme.Padding() * 2))) + + test.AssertRendersToMarkup(t, "accordion/layout_"+name+".xml", window.Canvas()) + + window.Close() + }) + } +} + +func TestAccordion_Layout_Expanded(t *testing.T) { + test.NewApp() + + for name, tt := range map[string]struct { + multiOpen bool + items []*widget.AccordionItem + opened []int + }{ + "expanded_single_open_one_item": { + items: []*widget.AccordionItem{ + { + Title: "A", + Detail: widget.NewLabel("11111"), + }, + }, + }, + "expanded_single_open_one_item_opened": { + items: []*widget.AccordionItem{ + { + Title: "A", + Detail: widget.NewLabel("11111"), + }, + }, + opened: []int{0}, + }, + "expanded_single_open_multiple_items": { + items: []*widget.AccordionItem{ + { + Title: "A", + Detail: widget.NewLabel("11111"), + }, + { + Title: "B", + Detail: widget.NewLabel("2222222222"), + }, + }, + }, + "expanded_single_open_multiple_items_opened": { + items: []*widget.AccordionItem{ + { + Title: "A", + Detail: widget.NewLabel("11111"), + }, + { + Title: "B", + Detail: widget.NewLabel("2222222222"), + }, + }, + opened: []int{0, 1}, + }, + "expanded_multiple_open_one_item": { + multiOpen: true, + items: []*widget.AccordionItem{ + { + Title: "A", + Detail: widget.NewLabel("11111"), + }, + }, + }, + "expanded_multiple_open_one_item_opened": { + multiOpen: true, + items: []*widget.AccordionItem{ + { + Title: "A", + Detail: widget.NewLabel("11111"), + }, + }, + opened: []int{0}, + }, + "expanded_multiple_open_multiple_items": { + multiOpen: true, + items: []*widget.AccordionItem{ + { + Title: "A", + Detail: widget.NewLabel("11111"), + }, + { + Title: "B", + Detail: widget.NewLabel("2222222222"), + }, + }, + }, + "expanded_multiple_open_multiple_items_opened": { + multiOpen: true, + items: []*widget.AccordionItem{ + { + Title: "A", + Detail: widget.NewLabel("11111"), + }, + { + Title: "B", + Detail: widget.NewLabel("2222222222"), + }, + }, + opened: []int{0, 1}, + }, + } { + t.Run(name, func(t *testing.T) { + accordion := &widget.Accordion{ + MultiOpen: tt.multiOpen, + } + for _, ai := range tt.items { + accordion.Append(ai) + } + for _, o := range tt.opened { + accordion.Open(o) + } + + window := test.NewWindow(&fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{accordion}}) + window.Resize(accordion.MinSize().Max(fyne.NewSize(150, 280))) test.AssertRendersToMarkup(t, "accordion/layout_"+name+".xml", window.Canvas()) diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml new file mode 100644 index 0000000000..9a5dc5e3c7 --- /dev/null +++ b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml @@ -0,0 +1,27 @@ + + + + + + + + + A + + + + + + + + B + + + + + + + + + + diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml new file mode 100644 index 0000000000..3c1d9517cd --- /dev/null +++ b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml @@ -0,0 +1,33 @@ + + + + + + + + + A + + + + + + + + B + + + + + 11111 + + + 2222222222 + + + + + + + + diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml b/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml new file mode 100644 index 0000000000..4e1c44b7a6 --- /dev/null +++ b/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml @@ -0,0 +1,16 @@ + + + + + + + + + A + + + + + + + diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml b/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml new file mode 100644 index 0000000000..a3c2e487f3 --- /dev/null +++ b/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml @@ -0,0 +1,19 @@ + + + + + + + + + A + + + + + 11111 + + + + + diff --git a/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml b/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml new file mode 100644 index 0000000000..9a5dc5e3c7 --- /dev/null +++ b/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml @@ -0,0 +1,27 @@ + + + + + + + + + A + + + + + + + + B + + + + + + + + + + diff --git a/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml new file mode 100644 index 0000000000..f9ac150210 --- /dev/null +++ b/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml @@ -0,0 +1,30 @@ + + + + + + + + + A + + + + + + + + B + + + + + 2222222222 + + + + + + + + diff --git a/widget/testdata/accordion/layout_expanded_single_open_one_item.xml b/widget/testdata/accordion/layout_expanded_single_open_one_item.xml new file mode 100644 index 0000000000..4e1c44b7a6 --- /dev/null +++ b/widget/testdata/accordion/layout_expanded_single_open_one_item.xml @@ -0,0 +1,16 @@ + + + + + + + + + A + + + + + + + diff --git a/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml b/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml new file mode 100644 index 0000000000..a3c2e487f3 --- /dev/null +++ b/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml @@ -0,0 +1,19 @@ + + + + + + + + + A + + + + + 11111 + + + + + diff --git a/widget/testdata/accordion/layout_multiple_open_multiple_items.xml b/widget/testdata/accordion/layout_multiple_open_multiple_items.xml index e56e8faf15..bb1c7b7d8f 100644 --- a/widget/testdata/accordion/layout_multiple_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_multiple_open_multiple_items.xml @@ -1,7 +1,7 @@ - + - - + + diff --git a/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml index 34b9faa2d6..9c0e2adf6a 100644 --- a/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml @@ -1,7 +1,7 @@ - + - - + + diff --git a/widget/testdata/accordion/layout_multiple_open_one_item.xml b/widget/testdata/accordion/layout_multiple_open_one_item.xml index bfbc48235a..17017f30bb 100644 --- a/widget/testdata/accordion/layout_multiple_open_one_item.xml +++ b/widget/testdata/accordion/layout_multiple_open_one_item.xml @@ -1,7 +1,7 @@ - + - - + + diff --git a/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml b/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml index 9326fb8f15..217136f83e 100644 --- a/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml @@ -1,7 +1,7 @@ - + - - + + diff --git a/widget/testdata/accordion/layout_single_open_multiple_items.xml b/widget/testdata/accordion/layout_single_open_multiple_items.xml index e56e8faf15..bb1c7b7d8f 100644 --- a/widget/testdata/accordion/layout_single_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_single_open_multiple_items.xml @@ -1,7 +1,7 @@ - + - - + + diff --git a/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml index 0c7bf69e07..13f2bb1166 100644 --- a/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml @@ -1,7 +1,7 @@ - + - - + + diff --git a/widget/testdata/accordion/layout_single_open_one_item.xml b/widget/testdata/accordion/layout_single_open_one_item.xml index bfbc48235a..17017f30bb 100644 --- a/widget/testdata/accordion/layout_single_open_one_item.xml +++ b/widget/testdata/accordion/layout_single_open_one_item.xml @@ -1,7 +1,7 @@ - + - - + + diff --git a/widget/testdata/accordion/layout_single_open_one_item_opened.xml b/widget/testdata/accordion/layout_single_open_one_item_opened.xml index 9326fb8f15..217136f83e 100644 --- a/widget/testdata/accordion/layout_single_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_single_open_one_item_opened.xml @@ -1,7 +1,7 @@ - + - - + +