package gio import ( "fmt" "strings" "gioui.org/layout" "gioui.org/unit" "gioui.org/widget/material" "softbox.local/core/application" ) func (shell *AppShell) layoutDetail( gtx layout.Context, theme *material.Theme, item application.CatalogListItem, ) layout.Dimensions { shell.detailRendered = true return panel( gtx, shellColors.muted, unit.Dp(6), layout.UniformInset(unit.Dp(12)), func(gtx layout.Context) layout.Dimensions { return layout.Flex{Axis: layout.Vertical}.Layout( gtx, layout.Rigid(func(gtx layout.Context) layout.Dimensions { return layout.Flex{Alignment: layout.Middle}.Layout( gtx, layout.Rigid(material.Body1(theme, "软件详情").Layout), layout.Flexed(1, layout.Spacer{}.Layout), layout.Rigid(func(gtx layout.Context) layout.Dimensions { return shell.layoutFilterButton( gtx, theme, &shell.closeDetail, "关闭", false, ) }), ) }), layout.Rigid(layout.Spacer{Height: unit.Dp(10)}.Layout), layout.Rigid(func(gtx layout.Context) layout.Dimensions { return layout.Center.Layout(gtx, func(gtx layout.Context) layout.Dimensions { return shell.layoutAppIcon( gtx, theme, item.ID, item.Name, unit.Dp(64), unit.Dp(7), ) }) }), layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout), layout.Rigid(func(gtx layout.Context) layout.Dimensions { return layout.Center.Layout(gtx, material.Body1(theme, item.Name).Layout) }), layout.Rigid(layout.Spacer{Height: unit.Dp(3)}.Layout), layout.Rigid(func(gtx layout.Context) layout.Dimensions { label := material.Caption( theme, fmt.Sprintf("%s · %s", item.ID, item.Version), ) label.Color = shellColors.secondary return layout.Center.Layout(gtx, label.Layout) }), layout.Rigid(layout.Spacer{Height: unit.Dp(10)}.Layout), layout.Rigid(func(gtx layout.Context) layout.Dimensions { return detailField(gtx, theme, "状态", statusLabel(item.Status)) }), layout.Rigid(func(gtx layout.Context) layout.Dimensions { return detailField(gtx, theme, "分类", fallbackText(item.Category, "未分类")) }), layout.Rigid(func(gtx layout.Context) layout.Dimensions { return detailField( gtx, theme, "标签", fallbackText(strings.Join(item.Tags, " · "), "无"), ) }), layout.Rigid(func(gtx layout.Context) layout.Dimensions { return detailField( gtx, theme, "简介", fallbackText(item.Description, "暂无简介"), ) }), layout.Rigid(func(gtx layout.Context) layout.Dimensions { if item.Reason == "" { return layout.Dimensions{} } return detailField(gtx, theme, "不可用原因", reasonLabel(item.Reason)) }), layout.Rigid(func(gtx layout.Context) layout.Dimensions { if item.Tutorial == "" { return layout.Dimensions{} } return detailField(gtx, theme, "教程", item.Tutorial) }), layout.Rigid(func(gtx layout.Context) layout.Dimensions { if item.Homepage == "" { return layout.Dimensions{} } return detailField(gtx, theme, "主页", item.Homepage) }), layout.Rigid(func(gtx layout.Context) layout.Dimensions { label := material.Caption(theme, "实际安装/启动操作将在后续用例接入") label.Color = shellColors.secondary return label.Layout(gtx) }), ) }, ) } func detailField( gtx layout.Context, theme *material.Theme, labelText string, value string, ) layout.Dimensions { return layout.Inset{Bottom: unit.Dp(8)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions { return layout.Flex{Axis: layout.Vertical}.Layout( gtx, layout.Rigid(func(gtx layout.Context) layout.Dimensions { label := material.Caption(theme, labelText) label.Color = shellColors.secondary return label.Layout(gtx) }), layout.Rigid(layout.Spacer{Height: unit.Dp(2)}.Layout), layout.Rigid(material.Caption(theme, value).Layout), ) }) } func fallbackText(value, fallback string) string { if value == "" { return fallback } return value } func reasonLabel(reason string) string { switch reason { case "deprecated": return "软件已停止发布" case "minimum_os": return "Windows 版本低于最低要求" case "architecture": return "没有当前架构的软件包" default: return reason } }