134 lines
4.2 KiB
Go
134 lines
4.2 KiB
Go
//go:build gl
|
||
|
||
// 界面屏幕:主菜单与暂停菜单(UI还原.md §2:布局/控件/版本角标复刻原版)。
|
||
package ui
|
||
|
||
// Button 一个按钮:区域 + 悬停高亮 + 标签纹理。
|
||
type Button struct {
|
||
X, Y, W, H float32
|
||
Tex uint32 // 标签纹理(预光栅化中文)
|
||
LabelW float32
|
||
LabelH float32
|
||
Action string
|
||
}
|
||
|
||
// TitleScreen 主菜单(UI还原.md §2:土质背景 + 标题 + 原版按钮 + 版本/版权角标)。
|
||
type TitleScreen struct {
|
||
TitleTex uint32
|
||
TitleW float32
|
||
TitleH float32
|
||
|
||
SplashTex uint32 // 黄色 splash 文本(原版风格)
|
||
SplashW float32
|
||
SplashH float32
|
||
|
||
BgTex uint32 // 土质背景(16px dirt 平铺预渲染)
|
||
BtnTex uint32 // 原版按钮控件(widget/button.png 200×20)
|
||
BtnHover uint32 // 悬停高亮(button_highlighted.png)
|
||
Buttons []Button
|
||
|
||
Version string // 左下角版本(原版角标)
|
||
Copyright string // 右下角版权
|
||
}
|
||
|
||
// HitTest 命中检测(按钮区域)。
|
||
func (s *TitleScreen) HitTest(mx, my float32) string {
|
||
for _, b := range s.Buttons {
|
||
if mx >= b.X && mx <= b.X+b.W && my >= b.Y && my <= b.Y+b.H {
|
||
return b.Action
|
||
}
|
||
}
|
||
return ""
|
||
}
|
||
|
||
// Draw 绘制主菜单(原版布局:背景 → 标题+splash → 按钮列 → 版本/版权角标)。
|
||
func (s *TitleScreen) Draw(r *Renderer, mx, my float32) {
|
||
w, h := float32(r.w), float32(r.h)
|
||
// 土质背景(UI还原.md §2 背景)
|
||
if s.BgTex != 0 {
|
||
r.pushQuad(quad{x: 0, y: 0, w: w, h: h, u0: 0, v0: 0, u1: 1, v1: 1,
|
||
r: 1, g: 1, b: 1, a: 1, tex: s.BgTex})
|
||
} else {
|
||
r.DrawRect(0, 0, w, h, [4]float32{0.08, 0.1, 0.12, 1})
|
||
}
|
||
// 标题(居中偏上,原版 logo 位置)
|
||
if s.TitleTex != 0 {
|
||
r.pushQuad(quad{x: w/2 - s.TitleW/2, y: h * 0.15, w: s.TitleW, h: s.TitleH,
|
||
u0: 0, v0: 0, u1: 1, v1: 1, r: 1, g: 1, b: 1, a: 1, tex: s.TitleTex})
|
||
}
|
||
// splash(标题右下,原版黄色倾斜文本——MVP 水平放置)
|
||
if s.SplashTex != 0 {
|
||
r.pushQuad(quad{x: w/2 + s.TitleW/2 - s.SplashW + 20, y: h*0.15 + s.TitleH, w: s.SplashW, h: s.SplashH,
|
||
u0: 0, v0: 0, u1: 1, v1: 1, r: 1, g: 1, b: 1, a: 1, tex: s.SplashTex})
|
||
}
|
||
// 按钮列(原版:居中偏下,200×20 控件 + 标签)
|
||
for _, b := range s.Buttons {
|
||
hover := mx >= b.X && mx <= b.X+b.W && my >= b.Y && my <= b.Y+b.H
|
||
tex := s.BtnTex
|
||
if hover && s.BtnHover != 0 {
|
||
tex = s.BtnHover
|
||
}
|
||
if tex != 0 {
|
||
r.pushQuad(quad{x: b.X, y: b.Y, w: b.W, h: b.H, u0: 0, v0: 0, u1: 1, v1: 1,
|
||
r: 1, g: 1, b: 1, a: 1, tex: tex})
|
||
}
|
||
if b.Tex != 0 {
|
||
// 标签居中
|
||
r.pushQuad(quad{x: b.X + (b.W-b.LabelW)/2, y: b.Y + (b.H-b.LabelH)/2, w: b.LabelW, h: b.LabelH,
|
||
u0: 0, v0: 0, u1: 1, v1: 1, r: 1, g: 1, b: 1, a: 1, tex: b.Tex})
|
||
}
|
||
}
|
||
// 版本角标(左下)与版权(右下,原版样式)
|
||
if s.Version != "" {
|
||
r.DrawText(8, h-12, s.Version, 1, [4]float32{1, 1, 1, 1})
|
||
}
|
||
if s.Copyright != "" {
|
||
r.DrawText(w-r.TextWidth(s.Copyright, 1)-8, h-12, s.Copyright, 1, [4]float32{1, 1, 1, 1})
|
||
}
|
||
}
|
||
|
||
// PauseScreen 暂停菜单(UI还原.md §2:半透明遮罩 + 原版按钮)。
|
||
type PauseScreen struct {
|
||
TitleTex uint32
|
||
TitleW float32
|
||
TitleH float32
|
||
BtnTex uint32
|
||
BtnHover uint32
|
||
Buttons []Button
|
||
}
|
||
|
||
// HitTest 命中检测。
|
||
func (s *PauseScreen) HitTest(mx, my float32) string {
|
||
for _, b := range s.Buttons {
|
||
if mx >= b.X && mx <= b.X+b.W && my >= b.Y && my <= b.Y+b.H {
|
||
return b.Action
|
||
}
|
||
}
|
||
return ""
|
||
}
|
||
|
||
// Draw 绘制暂停菜单。
|
||
func (s *PauseScreen) Draw(r *Renderer, mx, my float32) {
|
||
w, h := float32(r.w), float32(r.h)
|
||
r.DrawRect(0, 0, w, h, [4]float32{0, 0, 0, 0.6})
|
||
if s.TitleTex != 0 {
|
||
r.pushQuad(quad{x: w/2 - s.TitleW/2, y: h * 0.15, w: s.TitleW, h: s.TitleH,
|
||
u0: 0, v0: 0, u1: 1, v1: 1, r: 1, g: 1, b: 1, a: 1, tex: s.TitleTex})
|
||
}
|
||
for _, b := range s.Buttons {
|
||
hover := mx >= b.X && mx <= b.X+b.W && my >= b.Y && my <= b.Y+b.H
|
||
tex := s.BtnTex
|
||
if hover && s.BtnHover != 0 {
|
||
tex = s.BtnHover
|
||
}
|
||
if tex != 0 {
|
||
r.pushQuad(quad{x: b.X, y: b.Y, w: b.W, h: b.H, u0: 0, v0: 0, u1: 1, v1: 1,
|
||
r: 1, g: 1, b: 1, a: 1, tex: tex})
|
||
}
|
||
if b.Tex != 0 {
|
||
r.pushQuad(quad{x: b.X + (b.W-b.LabelW)/2, y: b.Y + (b.H-b.LabelH)/2, w: b.LabelW, h: b.LabelH,
|
||
u0: 0, v0: 0, u1: 1, v1: 1, r: 1, g: 1, b: 1, a: 1, tex: b.Tex})
|
||
}
|
||
}
|
||
}
|