package ui import ( "errors" "gioui.org/layout" "gioui.org/widget" "gioui.org/widget/material" "git.wxccs.org/iceking2nd/winauth-go/internal/hotkey" "git.wxccs.org/iceking2nd/winauth-go/internal/i18n" ) // hotkeyDialog edits the hotkey string of a single entry. It's a thin // wrapper around an Editor: validation runs synchronously on submit and // the caller is told the *parsed* value (still in canonical string // form, "" for clear). type hotkeyDialog struct { target *entry ed widget.Editor clearBt widget.Clickable okBt widget.Clickable cancelBt widget.Clickable errorMsg string } func newHotkeyDialog(target *entry) *hotkeyDialog { d := &hotkeyDialog{target: target} d.ed.SingleLine = true d.ed.SetText(target.Hotkey) return d } // hotkeyResult tells the caller what to do. cleared=true means remove // any existing hotkey. value is the canonical string ("Ctrl+Alt+G") if // set is true. type hotkeyResult struct { cancel bool cleared bool value string } func (d *hotkeyDialog) Layout( gtx layout.Context, th *material.Theme, onDone func(hotkeyResult), ) layout.Dimensions { if d.cancelBt.Clicked(gtx) { onDone(hotkeyResult{cancel: true}) return layout.Dimensions{Size: gtx.Constraints.Max} } if d.clearBt.Clicked(gtx) { onDone(hotkeyResult{cleared: true}) return layout.Dimensions{Size: gtx.Constraints.Max} } if d.okBt.Clicked(gtx) { txt := d.ed.Text() h, err := hotkey.Parse(txt) switch { case errors.Is(err, hotkey.ErrEmpty): onDone(hotkeyResult{cleared: true}) return layout.Dimensions{Size: gtx.Constraints.Max} case err != nil: d.errorMsg = err.Error() default: onDone(hotkeyResult{value: hotkey.Format(h)}) return layout.Dimensions{Size: gtx.Constraints.Max} } } body := func(gtx layout.Context) layout.Dimensions { return layout.Flex{Axis: layout.Vertical}.Layout(gtx, layout.Rigid(material.Body2(th, i18n.T("hotkey_intro")).Layout), layout.Rigid(layout.Spacer{Height: 8}.Layout), layout.Rigid(labeledEditor(th, i18n.T("label_hotkey"), &d.ed, "Ctrl+Alt+G")), layout.Rigid(errorLabel(th, d.errorMsg)), layout.Rigid(layout.Spacer{Height: 8}.Layout), layout.Rigid(func(gtx layout.Context) layout.Dimensions { return material.Button(th, &d.clearBt, i18n.T("btn_clear_hotkey")).Layout(gtx) }), ) } return modalCard(gtx, th, i18n.T("dialog_hotkey_title"), i18n.T("btn_ok"), i18n.T("btn_cancel"), &d.okBt, &d.cancelBt, body) }