Files
8bitMyGoUI/gallery/demos_input.go
T

261 lines
10 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package gallery
import (
"fmt"
"github.com/egoist/mygo/ui"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/icon"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/input"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
)
var inputEntries = []Entry{
{66, "Button", "按钮", "input", "Primary, normal, ghost and danger in three sizes. Pressing sinks the face a dot; loading spins and waits.", demoButton},
{67, "IconButton", "图标按钮", "input", "A square button with an icon and a name for screen readers.", demoIconButton},
{68, "ButtonGroup", "按钮组", "input", "Buttons joined edge to edge: one Tab stop, arrows move between them.", demoButtonGroup},
{69, "Toggle", "开关按钮", "input", "A button that stays sunken while it is on.", demoToggle},
{70, "ToggleGroup", "开关组", "input", "Joined toggles, for many choices or just one.", demoToggleGroup},
{71, "Checkbox", "复选框", "input", "An 8×8 box with a hand-placed check. Space toggles it.", demoCheckbox},
{72, "CheckboxGroup", "复选组", "input", "A parent box over children: mixed while some are checked, all or none on a click.", demoCheckboxGroup},
{73, "Radio", "单选", "input", "A pixel radio dot that picks its value.", demoRadio},
{74, "RadioGroup", "单选组", "input", "Radios as one Tab stop; the arrows choose.", demoRadioGroup},
{75, "Switch", "拨杆", "input", "A lever on an OFF/ON plate. Space flips it.", demoSwitch},
{76, "Slider", "滑块", "input", "A Well track, an Accent fill and a beveled knob: drag, arrows, Home, End.", demoSlider},
{77, "StepSlider", "刻度滑块", "input", "A slider that snaps to steps, with tick dots and its value.", demoStepSlider},
{78, "RangeSlider", "区间滑块", "input", "Two knobs for low and high that never cross.", demoRangeSlider},
{79, "Fader", "推子", "input", "A mixing-desk fader with a cap and ticks.", demoFader},
{80, "Stepper", "步进器", "input", "◀ value ▶ within bounds. Hold an arrow to repeat; keys step it too.", demoStepper},
{81, "NumberInput", "数字框", "input", "Type a number or step it with ▲▼ and the arrow keys; bad text turns the edge red.", demoNumberInput},
{82, "TextInput", "文本框", "input", "A one-line pixel field: caret, selection, input methods, clipboard. Enter submits.", demoTextInput},
{83, "PasswordInput", "密码框", "input", "Masked with ★; the eye shows the text.", demoPasswordInput},
{84, "TextArea", "多行文本", "input", "Many lines in its own scroll, following the caret, with a character count.", demoTextArea},
{85, "SearchField", "搜索框", "input", "A field with a magnifier. Escape clears it, Enter searches.", demoSearchField},
}
type inputDemo struct {
toggle, music, sound, check, lever bool
toggles, mode, party []bool
radio string
choice, level, count int
volume, steps, low, high, fader float64
price float64
name, secret, notes, query string
}
func inputState(c *ui.Context) *inputDemo {
return ui.Local(c.Root(), demoKey("input"), func() inputDemo {
return inputDemo{music: true, toggles: []bool{true, false, false}, mode: []bool{false, true, false}, party: []bool{true, false, true},
radio: "knight", choice: 1, level: 3, count: 5, volume: 0.6, steps: 40, low: 20, high: 70, fader: 0.3, price: 9.5}
})
}
func demoButton(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Column(c).Gap(k.D(6)).Children(func() {
ui.Row(c).Gap(k.D(4)).AlignItems(ui.Center).Children(func() {
for i, v := range []input.Variant{input.Primary, input.Normal, input.Ghost, input.Danger} {
name := []string{"PRIMARY", "NORMAL", "GHOST", "DANGER"}[i]
if input.Button(c, name, input.ButtonOptions{Variant: v}).Clicked {
log(name)
}
}
})
ui.Row(c).Gap(k.D(4)).AlignItems(ui.Center).Children(func() {
for _, b := range []struct {
name string
o input.ButtonOptions
}{{"Small", input.ButtonOptions{Size: input.Small}}, {"Save", input.ButtonOptions{Icon: icon.Save}}, {"BIG", input.ButtonOptions{Size: input.Large, Variant: input.Primary}}} {
if input.Button(c, b.name, b.o).Clicked {
log(b.name)
}
}
input.Button(c, "Saving", input.ButtonOptions{Loading: true})
input.Button(c, "Off", input.ButtonOptions{Disabled: true})
})
})
}
func demoIconButton(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Row(c).Gap(k.D(4)).Children(func() {
for _, n := range []icon.Named{{Name: "Play", Sprite: icon.Play}, {Name: "Pause", Sprite: icon.Pause}, {Name: "Stop", Sprite: icon.Stop}} {
if input.IconButton(c, n.Sprite, n.Name, input.IconButtonOptions{}).Clicked {
log(n.Name)
}
}
if input.IconButton(c, icon.Trash, "Delete", input.IconButtonOptions{Variant: input.Danger}).Clicked {
log("Delete")
}
})
}
func demoButtonGroup(c *ui.Context, log func(string)) {
labels := []string{"FIGHT", "MAGIC", "ITEM", "RUN"}
if r := input.ButtonGroup(c, labels, input.ButtonGroupOptions{Label: "Command"}); r.Clicked >= 0 {
log(labels[r.Clicked])
}
}
func demoToggle(c *ui.Context, log func(string)) {
k := pixel.K(c)
s := inputState(c)
ui.Row(c).Gap(k.D(4)).Children(func() {
if input.Toggle(c, "MUSIC", &s.music, input.ToggleOptions{Icon: icon.Music}).Changed {
log(fmt.Sprintf("music %v", s.music))
}
if input.Toggle(c, "SOUND", &s.sound, input.ToggleOptions{Icon: icon.Volume}).Changed {
log(fmt.Sprintf("sound %v", s.sound))
}
})
}
func demoToggleGroup(c *ui.Context, log func(string)) {
k := pixel.K(c)
s := inputState(c)
ui.Column(c).Gap(k.D(6)).Children(func() {
if input.ToggleGroup(c, []string{"B", "I", "U"}, s.toggles, input.ToggleGroupOptions{Label: "Style"}).Changed {
log(fmt.Sprintf("style %v", s.toggles))
}
if input.ToggleGroup(c, []string{"EASY", "NORMAL", "HARD"}, s.mode, input.ToggleGroupOptions{Single: true, Label: "Mode"}).Changed {
log(fmt.Sprintf("mode %v", s.mode))
}
})
}
func demoCheckbox(c *ui.Context, log func(string)) {
k := pixel.K(c)
s := inputState(c)
ui.Column(c).Gap(k.D(2)).Children(func() {
if input.Checkbox(c, "Remember me", &s.check, input.CheckboxOptions{}).Changed {
log(fmt.Sprintf("remember %v", s.check))
}
locked := true
input.Checkbox(c, "Hard mode (locked)", &locked, input.CheckboxOptions{Disabled: true})
})
}
func demoCheckboxGroup(c *ui.Context, log func(string)) {
s := inputState(c)
if input.CheckboxGroup(c, "Party", []string{"Knight", "Mage", "Thief"}, s.party, input.CheckboxGroupOptions{}).Changed {
log(fmt.Sprintf("party %v", s.party))
}
}
func demoRadio(c *ui.Context, log func(string)) {
k := pixel.K(c)
s := inputState(c)
ui.Column(c).Gap(k.D(2)).Children(func() {
for _, class := range []string{"knight", "mage", "thief"} {
if input.Radio(c, class, class, &s.radio, input.RadioOptions{}).Changed {
log("class " + class)
}
}
})
}
func demoRadioGroup(c *ui.Context, log func(string)) {
labels := []string{"Spring", "Summer", "Autumn", "Winter"}
s := inputState(c)
if input.RadioGroup(c, labels, &s.choice, input.RadioGroupOptions{Row: true, Label: "Season"}).Changed {
log("season " + labels[s.choice])
}
}
func demoSwitch(c *ui.Context, log func(string)) {
s := inputState(c)
if input.Switch(c, "Power", &s.lever, input.SwitchOptions{}).Changed {
log(fmt.Sprintf("power %v", s.lever))
}
}
func demoSlider(c *ui.Context, log func(string)) {
k := pixel.K(c)
s := inputState(c)
ui.Row(c).Gap(k.D(6)).AlignItems(ui.Center).Children(func() {
if input.Slider(c, "Volume", &s.volume, input.SliderOptions{Width: 120}).Changed {
log(fmt.Sprintf("volume %.2f", s.volume))
}
pixel.Text(c, fmt.Sprintf("%3.0f%%", s.volume*100), pixel.TextOptions{})
})
}
func demoStepSlider(c *ui.Context, log func(string)) {
s := inputState(c)
if input.StepSlider(c, "Speed", &s.steps, input.StepSliderOptions{Min: 0, Max: 100, Step: 20, Width: 120}).Changed {
log(fmt.Sprintf("speed %g", s.steps))
}
}
func demoRangeSlider(c *ui.Context, log func(string)) {
k := pixel.K(c)
s := inputState(c)
ui.Row(c).Gap(k.D(6)).AlignItems(ui.Center).Children(func() {
if input.RangeSlider(c, "Level range", &s.low, &s.high, input.RangeSliderOptions{Min: 1, Max: 99, Width: 140}).Changed {
log(fmt.Sprintf("levels %.0f–%.0f", s.low, s.high))
}
pixel.Text(c, fmt.Sprintf("LV %.0f–%.0f", s.low, s.high), pixel.TextOptions{})
})
}
func demoFader(c *ui.Context, log func(string)) {
s := inputState(c)
if input.Fader(c, "Master", &s.fader, input.FaderOptions{}).Changed {
log(fmt.Sprintf("master %.2f", s.fader))
}
}
func demoStepper(c *ui.Context, log func(string)) {
s := inputState(c)
if input.Stepper(c, "Lives", &s.count, input.StepperOptions{Min: 1, Max: 9}).Changed {
log(fmt.Sprintf("lives %d", s.count))
}
}
func demoNumberInput(c *ui.Context, log func(string)) {
s := inputState(c)
if input.NumberInput(c, "Price", &s.price, input.NumberInputOptions{Min: 0, Max: 999, Step: 0.5, Width: 80}).Changed {
log(fmt.Sprintf("price %g", s.price))
}
}
func demoTextInput(c *ui.Context, log func(string)) {
s := inputState(c)
r := input.TextInput(c, "Hero name", &s.name, input.TextInputOptions{Placeholder: "Your name 你的名字", MaxLength: 12})
if r.Changed {
log("name " + s.name)
}
if r.Submitted {
log("submitted " + s.name)
}
}
func demoPasswordInput(c *ui.Context, log func(string)) {
s := inputState(c)
r := input.PasswordInput(c, "Password", &s.secret, input.PasswordInputOptions{Placeholder: "Password"})
if r.Changed {
log(fmt.Sprintf("%d characters", len([]rune(s.secret))))
}
if r.Submitted {
log("signed in")
}
}
func demoTextArea(c *ui.Context, log func(string)) {
s := inputState(c)
if input.TextArea(c, "Notes", &s.notes, input.TextAreaOptions{Placeholder: "Dear diary...", MaxLength: 140, Width: 200, Lines: 4}).Changed {
log(fmt.Sprintf("%d characters", len([]rune(s.notes))))
}
}
func demoSearchField(c *ui.Context, log func(string)) {
s := inputState(c)
r := input.SearchField(c, "Find items", &s.query, input.SearchFieldOptions{Placeholder: "Potion, sword...", Width: 160})
if r.Changed {
log("query " + s.query)
}
if r.Submitted {
log("search " + s.query)
}
}