forked from go/golangs_learn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
3.5 KiB
136 lines
3.5 KiB
package discloser
|
|
|
|
import (
|
|
"gioui.org/layout"
|
|
"gioui.org/unit"
|
|
"gioui.org/widget"
|
|
"gioui.org/widget/material"
|
|
"gioui.org/x/component"
|
|
|
|
"gioui.org/example/component/icon"
|
|
page "gioui.org/example/component/pages"
|
|
)
|
|
|
|
// TreeNode is a simple tree implementation that holds both
|
|
// display data and the state for Discloser widgets. In
|
|
// practice, you'll often want to separate the state from
|
|
// the data being presented.
|
|
type TreeNode struct {
|
|
Text string
|
|
Children []TreeNode
|
|
component.DiscloserState
|
|
}
|
|
|
|
type (
|
|
C = layout.Context
|
|
D = layout.Dimensions
|
|
)
|
|
|
|
// Page holds the state for a page demonstrating the features of
|
|
// the AppBar component.
|
|
type Page struct {
|
|
TreeNode
|
|
widget.List
|
|
*page.Router
|
|
CustomDiscloserState component.DiscloserState
|
|
}
|
|
|
|
// New constructs a Page with the provided router.
|
|
func New(router *page.Router) *Page {
|
|
return &Page{
|
|
Router: router,
|
|
TreeNode: TreeNode{
|
|
Text: "Expand Me",
|
|
Children: []TreeNode{
|
|
{
|
|
Text: "Disclosers can be (expand me)...",
|
|
Children: []TreeNode{
|
|
{
|
|
Text: "...nested to arbitrary depths.",
|
|
},
|
|
{
|
|
Text: "There are also types available to customize the look and feel of the discloser:",
|
|
Children: []TreeNode{
|
|
{
|
|
Text: "• DiscloserStyle lets you provide your own control instead of the default triangle used here.",
|
|
},
|
|
{
|
|
Text: "• DiscloserArrowStyle lets you alter the presentation of the triangle used here, like changing its color, size, left/right anchoring, or margin.",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
var _ page.Page = &Page{}
|
|
|
|
func (p *Page) Actions() []component.AppBarAction {
|
|
return []component.AppBarAction{}
|
|
}
|
|
|
|
func (p *Page) Overflow() []component.OverflowAction {
|
|
return []component.OverflowAction{}
|
|
}
|
|
|
|
func (p *Page) NavItem() component.NavItem {
|
|
return component.NavItem{
|
|
Name: "Disclosers",
|
|
Icon: icon.VisibilityIcon,
|
|
}
|
|
}
|
|
|
|
// LayoutTreeNode recursively lays out a tree of widgets described by
|
|
// TreeNodes.
|
|
func (p *Page) LayoutTreeNode(gtx C, th *material.Theme, tn *TreeNode) D {
|
|
if len(tn.Children) == 0 {
|
|
return layout.UniformInset(unit.Dp(2)).Layout(gtx,
|
|
material.Body1(th, tn.Text).Layout)
|
|
}
|
|
children := make([]layout.FlexChild, 0, len(tn.Children))
|
|
for i := range tn.Children {
|
|
child := &tn.Children[i]
|
|
children = append(children, layout.Rigid(
|
|
func(gtx C) D {
|
|
return p.LayoutTreeNode(gtx, th, child)
|
|
}))
|
|
}
|
|
return component.SimpleDiscloser(th, &tn.DiscloserState).Layout(gtx,
|
|
material.Body1(th, tn.Text).Layout,
|
|
func(gtx C) D {
|
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, children...)
|
|
})
|
|
}
|
|
|
|
// LayoutCustomDiscloser demonstrates how to create a custom control for
|
|
// a discloser.
|
|
func (p *Page) LayoutCustomDiscloser(gtx C, th *material.Theme) D {
|
|
return component.Discloser(th, &p.CustomDiscloserState).Layout(gtx,
|
|
func(gtx C) D {
|
|
var l material.LabelStyle
|
|
l = material.Body1(th, "+")
|
|
if p.CustomDiscloserState.Visible() {
|
|
l.Text = "-"
|
|
}
|
|
l.Font.Variant = "Mono"
|
|
return layout.UniformInset(unit.Dp(2)).Layout(gtx, l.Layout)
|
|
},
|
|
material.Body1(th, "Custom Control").Layout,
|
|
material.Body2(th, "This control only took 9 lines of code.").Layout,
|
|
)
|
|
}
|
|
|
|
func (p *Page) Layout(gtx C, th *material.Theme) D {
|
|
p.List.Axis = layout.Vertical
|
|
return material.List(th, &p.List).Layout(gtx, 2, func(gtx C, index int) D {
|
|
return layout.UniformInset(unit.Dp(4)).Layout(gtx, func(gtx C) D {
|
|
if index == 0 {
|
|
return p.LayoutTreeNode(gtx, th, &p.TreeNode)
|
|
}
|
|
return p.LayoutCustomDiscloser(gtx, th)
|
|
})
|
|
})
|
|
}
|
|
|