diff --git a/cmd/main.go b/cmd/gin-service/main.go similarity index 100% rename from cmd/main.go rename to cmd/gin-service/main.go diff --git a/cmd/gio-service/main.go b/cmd/gio-service/main.go new file mode 100644 index 0000000..bde739c --- /dev/null +++ b/cmd/gio-service/main.go @@ -0,0 +1,175 @@ +package main + +import ( + "fmt" + "image/color" + "log" + "os" + + "gioui.org/app" + "gioui.org/font/gofont" + "gioui.org/layout" + "gioui.org/op" + "gioui.org/op/clip" + "gioui.org/op/paint" + "gioui.org/text" + "gioui.org/unit" + "gioui.org/widget" + "gioui.org/widget/material" +) + +// 定义侧边栏项目 +type SidebarItem struct { + Text string + Btn widget.Clickable // 处理点击事件 + ID int // 用于唯一标识每个项目 +} + +// 应用状态 +type AppState struct { + SidebarItems []SidebarItem + SelectedItemID int // 当前选中的项目ID + SelectedItemID2 int +} + +func main() { + go func() { + window := new(app.Window) + window.Option(app.Title("Go Desk"), app.Size(unit.Dp(1200), unit.Dp(800))) + + err := run(window) + if err != nil { + log.Fatal(err) + } + os.Exit(0) + }() + app.Main() +} + +func run(window *app.Window) error { + theme := material.NewTheme() + theme.Shaper = text.NewShaper(text.WithCollection(gofont.Collection())) + // 初始化应用状态 + var state AppState + state.SelectedItemID = 1 // 默认选中第一个项目 + // 初始化侧边栏项目 + state.SidebarItems = []SidebarItem{ + {Text: "仪表盘", ID: 1}, + {Text: "文件", ID: 2}, + {Text: "设置", ID: 3}, + {Text: "帮助", ID: 4}, + } + + // 初始化一个按钮组件 + var btn widget.Clickable + var ops op.Ops + for { + switch e := window.Event().(type) { + case app.DestroyEvent: + return e.Err + case app.FrameEvent: + // This graphics context is used for managing the rendering state. + gtx := app.NewContext(&ops, e) + + // Define an large label with an appropriate text: + title := material.H1(theme, "Hello, Gio") + + // Change the color of the label. + maroon := color.NRGBA{R: 127, G: 0, B: 0, A: 255} + title.Color = maroon + + // Change the position of the label. + title.Alignment = text.Middle + // 处理侧边栏按钮点击 + for i := range state.SidebarItems { + if state.SidebarItems[i].Btn.Clicked(gtx) { + fmt.Printf("Item %d clicked\n", state.SidebarItems[i].ID) + state.SelectedItemID = state.SidebarItems[i].ID // 更新选中状态 + // 这里可以触发其他操作,如加载新的内容页面 + } + } + // 开始绘制界面 + layout.Flex{ + Axis: layout.Horizontal, + }.Layout(gtx, + // 侧边栏 + layout.Rigid(func(gtx layout.Context) layout.Dimensions { + return drawSidebar(gtx, theme, &state) + }), + // 主内容区 (此处简化,仅显示文本) + layout.Flexed(1, func(gtx layout.Context) layout.Dimensions { + return material.Body1(theme, fmt.Sprintf("当前显示的内容: Item %d", state.SelectedItemID)).Layout(gtx) + }), + ) + // Draw the label to the graphics context. + title.Layout(gtx) + // 监听按钮点击事件 + for btn.Clicked(gtx) { + fmt.Println("按钮被点击了!") + } + + // 使用布局中心化内容 + layout.Center.Layout(gtx, func(gtx layout.Context) layout.Dimensions { + // 创建按钮并使用Material Design样式 + return material.Button(theme, &btn, "点我").Layout(gtx) + }) + // Pass the drawing operations to the GPU. + e.Frame(gtx.Ops) + } + } +} + +// drawSidebar 绘制侧边栏 +func drawSidebar(gtx layout.Context, th *material.Theme, state *AppState) layout.Dimensions { + // 侧边栏背景和样式 + sidebarBackground := func(gtx layout.Context, w layout.Widget) layout.Dimensions { + return material.Background(gtx, "", w) /* 设置背景颜色 */ + } + + return layout.Stack{}.Layout(gtx, + layout.Expanded(sidebarBackground), + layout.Stacked(func(gtx layout.Context) layout.Dimensions { + // 使用列表布局排列侧边栏项目 + list := layout.List{ + Axis: layout.Vertical, + } + return list.Layout(gtx, len(state.SidebarItems), func(gtx layout.Context, index int) layout.Dimensions { + item := &state.SidebarItems[index] + // 根据是否选中决定样式 + bgColor := "" /* 默认背景色 */ + textColor := "" /* 默认文字颜色 */ + if item.ID == state.SelectedItemID { + bgColor = "" /* 选中时的背景色,例如 primary color */ + textColor = "" /* 选中时的文字颜色,例如 on primary color */ + } + + // 绘制可点击的按钮,应用选中的样式 + return material.Clickable(gtx, &item.Btn, func(gtx layout.Context) layout.Dimensions { + // 填充背景色 (选中与否颜色不同) + return layout.Background{}.Layout(gtx, + func(gtx layout.Context) layout.Dimensions { + return fill(gtx, bgColor) + }, + func(gtx layout.Context) layout.Dimensions { + // 添加边距和布局 + return layout.Inset{Top: unit.Dp(5), Bottom: unit.Dp(5), Left: unit.Dp(10), Right: unit.Dp(10)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions { + // 显示文字 + label := material.Body1(th, item.Text) + label.Color = textColor + return label.Layout(gtx) + }) + }, + ) + }) + }) + }), + ) +} + +// fill 用指定颜色填充区域 +func fill(gtx layout.Context, color color.NRGBA) layout.Dimensions { + defer clip.Rect{Max: gtx.Constraints.Max}.Push(gtx.Ops).Pop() + paint.ColorOp{Color: color}.Add(gtx.Ops) + paint.PaintOp{}.Add(gtx.Ops) + return layout.Dimensions{Size: gtx.Constraints.Max} +} diff --git a/go.mod b/go.mod index e5e6126..5cd2943 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module go-desk go 1.24.3 require ( + gioui.org v0.8.0 // indirect + gioui.org/shader v1.0.8 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bytedance/sonic v1.11.6 // indirect @@ -20,6 +22,7 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/go-text/typesetting v0.2.1 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/uuid v1.6.0 // indirect @@ -102,6 +105,8 @@ require ( golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.39.0 // indirect golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 // indirect + golang.org/x/exp/shiny v0.0.0-20240707233637-46b078467d37 // indirect + golang.org/x/image v0.18.0 // indirect golang.org/x/mod v0.25.0 // indirect golang.org/x/net v0.41.0 // indirect golang.org/x/sync v0.15.0 // indirect