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.

195 lines
5.4 KiB

package textfield
import (
"image/color"
"unicode"
"gioui.org/layout"
"gioui.org/op"
"gioui.org/widget"
"gioui.org/widget/material"
"gioui.org/x/component"
alo "gioui.org/example/component/applayout"
"gioui.org/example/component/icon"
page "gioui.org/example/component/pages"
)
type (
C = layout.Context
D = layout.Dimensions
)
// Page holds the state for a page demonstrating the features of
// the TextField component.
type Page struct {
inputAlignment layout.Alignment
inputAlignmentEnum widget.Enum
nameInput, addressInput, priceInput, tweetInput, numberInput component.TextField
widget.List
*page.Router
}
// New constructs a Page with the provided router.
func New(router *page.Router) *Page {
return &Page{
Router: router,
}
}
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: "Text Field Features",
Icon: icon.EditIcon,
}
}
func (p *Page) Layout(gtx C, th *material.Theme) D {
p.List.Axis = layout.Vertical
return material.List(th, &p.List).Layout(gtx, 1, func(gtx C, _ int) D {
return layout.Flex{
Axis: layout.Vertical,
}.Layout(
gtx,
layout.Rigid(func(gtx C) D {
p.nameInput.Alignment = p.inputAlignment
return p.nameInput.Layout(gtx, th, "Name")
}),
layout.Rigid(func(gtx C) D {
return alo.DefaultInset.Layout(gtx, material.Body2(th, "Responds to hover events.").Layout)
}),
layout.Rigid(func(gtx C) D {
p.addressInput.Alignment = p.inputAlignment
return p.addressInput.Layout(gtx, th, "Address")
}),
layout.Rigid(func(gtx C) D {
return alo.DefaultInset.Layout(gtx, material.Body2(th, "Label animates properly when you click to select the text field.").Layout)
}),
layout.Rigid(func(gtx C) D {
p.priceInput.Prefix = func(gtx C) D {
th := *th
th.Palette.Fg = color.NRGBA{R: 100, G: 100, B: 100, A: 255}
return material.Label(&th, th.TextSize, "$").Layout(gtx)
}
p.priceInput.Suffix = func(gtx C) D {
th := *th
th.Palette.Fg = color.NRGBA{R: 100, G: 100, B: 100, A: 255}
return material.Label(&th, th.TextSize, ".00").Layout(gtx)
}
p.priceInput.SingleLine = true
p.priceInput.Alignment = p.inputAlignment
return p.priceInput.Layout(gtx, th, "Price")
}),
layout.Rigid(func(gtx C) D {
return alo.DefaultInset.Layout(gtx, material.Body2(th, "Can have prefix and suffix elements.").Layout)
}),
layout.Rigid(func(gtx C) D {
if err := func() string {
for _, r := range p.numberInput.Text() {
if !unicode.IsDigit(r) {
return "Must contain only digits"
}
}
return ""
}(); err != "" {
p.numberInput.SetError(err)
} else {
p.numberInput.ClearError()
}
p.numberInput.SingleLine = true
p.numberInput.Alignment = p.inputAlignment
return p.numberInput.Layout(gtx, th, "Number")
}),
layout.Rigid(func(gtx C) D {
return alo.DefaultInset.Layout(gtx, material.Body2(th, "Can be validated.").Layout)
}),
layout.Rigid(func(gtx C) D {
if p.tweetInput.TextTooLong() {
p.tweetInput.SetError("Too many characters")
} else {
p.tweetInput.ClearError()
}
p.tweetInput.CharLimit = 128
p.tweetInput.Helper = "Tweets have a limited character count"
p.tweetInput.Alignment = p.inputAlignment
return p.tweetInput.Layout(gtx, th, "Tweet")
}),
layout.Rigid(func(gtx C) D {
return alo.DefaultInset.Layout(gtx, material.Body2(th, "Can have a character counter and help text.").Layout)
}),
layout.Rigid(func(gtx C) D {
if p.inputAlignmentEnum.Changed() {
switch p.inputAlignmentEnum.Value {
case layout.Start.String():
p.inputAlignment = layout.Start
case layout.Middle.String():
p.inputAlignment = layout.Middle
case layout.End.String():
p.inputAlignment = layout.End
default:
p.inputAlignment = layout.Start
}
op.InvalidateOp{}.Add(gtx.Ops)
}
return alo.DefaultInset.Layout(
gtx,
func(gtx C) D {
return layout.Flex{
Axis: layout.Vertical,
}.Layout(
gtx,
layout.Rigid(func(gtx C) D {
return material.Body2(th, "Text Alignment").Layout(gtx)
}),
layout.Rigid(func(gtx C) D {
return layout.Flex{
Axis: layout.Vertical,
}.Layout(
gtx,
layout.Rigid(func(gtx C) D {
return material.RadioButton(
th,
&p.inputAlignmentEnum,
layout.Start.String(),
"Start",
).Layout(gtx)
}),
layout.Rigid(func(gtx C) D {
return material.RadioButton(
th,
&p.inputAlignmentEnum,
layout.Middle.String(),
"Middle",
).Layout(gtx)
}),
layout.Rigid(func(gtx C) D {
return material.RadioButton(
th,
&p.inputAlignmentEnum,
layout.End.String(),
"End",
).Layout(gtx)
}),
)
}),
)
},
)
}),
layout.Rigid(func(gtx C) D {
return alo.DefaultInset.Layout(gtx, material.Body2(th, "This text field implementation was contributed by Jack Mordaunt. Thanks Jack!").Layout)
}),
)
})
}