Files
winauth-go/internal/ui/dialog_welcome.go
T
iceking2nd 133091a32e feat(ui): 首次启动加密引导 + 真窗口图标 (.syso)
首次启动:
- 配置文件不存在时弹欢迎对话框:选「启用密码保护」或「稍后再说」
- 选启用直接进 setPasswordDialog,OK 时 store.SetPassword 触发首次保存
- io/fs.ErrNotExist 检测新分支
- modalCard 抽出 modalShell 内核以便 welcomeDialog 自定义 footer

真窗口图标:
- tools/gen_ico 从 PNG 生成多分辨率 .ico(7 尺寸:16~256)
- 提交 rsrc_windows.syso(rsrc 通过 goproxy.cn 生成),go build 自动链入
- tray_windows.go 改用嵌入资源 ID=1,失败 fallback IDI_APPLICATION
- README 更新完整的图标生成流程
2026-06-12 10:07:13 +08:00

67 lines
2.1 KiB
Go

package ui
import (
"gioui.org/layout"
"gioui.org/unit"
"gioui.org/widget"
"gioui.org/widget/material"
"git.wxccs.org/iceking2nd/winauth-go/internal/i18n"
)
// welcomeDialog is the first-run prompt. Triggered when the config
// file does not exist. The user picks between enabling password
// protection and skipping — both branches hand control back to the
// caller via onDone.
type welcomeDialog struct {
enableBtn widget.Clickable
skipBtn widget.Clickable
}
func newWelcomeDialog() *welcomeDialog {
return &welcomeDialog{}
}
// welcomeResult is what onDone receives. encrypt=true means the user
// picked "Enable password protection" and the caller should raise the
// setPasswordDialog next. skip=true means the user dismissed the prompt
// and we should start with an empty, unencrypted config.
type welcomeResult struct {
encrypt bool
skip bool
}
func (d *welcomeDialog) Layout(
gtx layout.Context, th *material.Theme,
onDone func(welcomeResult),
) layout.Dimensions {
if d.enableBtn.Clicked(gtx) {
onDone(welcomeResult{encrypt: true})
return layout.Dimensions{Size: gtx.Constraints.Max}
}
if d.skipBtn.Clicked(gtx) {
onDone(welcomeResult{skip: true})
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.Body1(th, i18n.T("msg_welcome_intro")).Layout),
)
}
// Custom footer: two side-by-side actions. Use the shared modalShell
// to reuse the standard backdrop/title/inset; only the action row
// differs from the OK/Cancel modalCard pattern.
footer := func(gtx layout.Context) layout.Dimensions {
return layout.Flex{Axis: layout.Horizontal, Spacing: layout.SpaceStart}.Layout(gtx,
layout.Rigid(material.Button(th, &d.enableBtn, i18n.T("btn_welcome_enable_password")).Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return layout.Inset{Left: unit.Dp(8)}.Layout(gtx,
material.Button(th, &d.skipBtn, i18n.T("btn_welcome_skip")).Layout)
}),
)
}
return modalShell(gtx, th, i18n.T("dialog_welcome_title"), body, footer)
}