Layout: review r3 fix

This commit is contained in:
ZacharyZhang-NY committed 2026-10-05 13:06:24 -04:00
1 parent 93acbdec68
commit b34958b01b
3 files changed
+54 -7

No files matched your search

+1
View File
@@ -47,6 +47,7 @@ if bar.Clicked == "bell" {
- 操作条目:悬停 SurfaceHover,按下 Selection,键盘焦点环。
- 折叠:按“右组末项 → 左组首项”的顺序隐藏 `Secondary` 条目,直到放得下(按实际宽度计算,操作条目至少 28 DIP,含条目间距);显示 `+N` 按钮,无障碍名称为“另有 N 项”,点击或 Enter/Space 打开弹层,列出被隐藏的条目,其中的操作照常可用,执行后弹层关闭。主要条目永不隐藏。
- 文本放大时状态栏随文字增高。
- 焦点所在条目被折叠时,焦点移到收纳它的 `+N` 按钮上,不会丢失。
- 进度:AccentText 填充,Border 轨道,描述为百分比。
## 事件
+17 -7
View File
@@ -70,19 +70,25 @@ func StatusBar(c *ui.Context, opts StatusBarOptions) StatusBarResult {
hidden := statusBarHide(c, opts, was.W-d.Unit()*4, gap)
open := ui.Local(e, "status_bar.open", func() bool { return false })
*open = *open && len(hidden) > 0
// focused is the bar item that had the focus last frame, for moving it to "+N" when that item folds.
focused := ui.Local(e, "status_bar.focused", func() string { return "" })
wasFocused := *focused
*focused = ""
var res StatusBarResult
item := func(it StatusItem) {
if statusBarItem(c, it) {
item := func(it StatusItem) bool {
clicked, hasFocus := statusBarItem(c, it)
if clicked {
res.Clicked = it.ID
*open = false
slog.Debug("mujica: status_bar clicked", "id", it.ID)
}
return hasFocus
}
group := func(key string, items []StatusItem) {
ui.Row(c).Key(key).Gap(gap).Shrink(0).Dividers(theme.BorderWidth, k.Border).Children(func() {
for _, it := range items {
if !hidden[it.ID] {
item(it)
if !hidden[it.ID] && item(it) {
*focused = it.ID
}
}
})
@@ -92,6 +98,10 @@ func StatusBar(c *ui.Context, opts StatusBarOptions) StatusBarResult {
ui.Spacer(c).Key("status_bar.spacer")
if len(hidden) > 0 {
more := statusBarMore(c, len(hidden))
if wasFocused != "" && hidden[wasFocused] {
more.Focus()
slog.Debug("mujica: status_bar focus folded", "id", wasFocused)
}
if more.Clicked() {
*open = !*open
slog.Debug("mujica: status_bar hidden items", "open", *open)
@@ -217,8 +227,8 @@ func statusBarWidth(c *ui.Context, it StatusItem) float32 {
return w
}
// statusBarItem builds one item and reports whether its action was clicked.
func statusBarItem(c *ui.Context, it StatusItem) bool {
// statusBarItem builds one item and reports whether its action was clicked and whether it has the focus.
func statusBarItem(c *ui.Context, it StatusItem) (clicked, focused bool) {
k := Tokens(c)
d := Density(c)
fg := k.TextMuted
@@ -265,7 +275,7 @@ func statusBarItem(c *ui.Context, it StatusItem) bool {
statusBarProgress(c, it.Progress)
}
})
return it.Action && e.Clicked()
return it.Action && e.Clicked(), e.FocusWithin()
}
func statusBarProgress(c *ui.Context, v float32) {
+36
View File
@@ -286,3 +286,39 @@ func TestStatusBarKeepsFocusAcrossDensity(t *testing.T) {
t.Fatalf("Enter after the switch activated %d times, want 1", n)
}
}
func TestStatusBarFocusMovesToMoreWhenFocusedItemFolds(t *testing.T) {
density := theme.Default
var clicked []string
o := StatusBarOptions{
Left: []StatusItem{{ID: "main", Text: "main"}, {ID: "fmt", Text: "Format", Action: true, Secondary: true}},
Right: []StatusItem{{ID: "bell", Label: "Notifications", Icon: icons.Must("bell"), Action: true}},
}
tt := ui.NewTester(func(c *ui.Context) {
Use(c, Settings{Density: density})
if id := StatusBar(c, o).Clicked; id != "" {
clicked = append(clicked, id)
}
}, 152, 300)
tt.Key(0, ui.KeyTab)
if !tt.Focused("Format") {
t.Fatal("Tab did not focus Format at Default density")
}
density = theme.Comfortable
tt.Frame()
if tt.HasText("Format") {
t.Fatal("Format did not fold at Comfortable density")
}
if !tt.Focused("1 more items") {
t.Fatal("focus did not move to the +N button that holds Format")
}
tt.Key(0, ui.KeyEnter)
if !tt.HasText("Format") {
t.Fatal("Enter on +N did not open the list with Format")
}
tt.Key(0, ui.KeyTab)
tt.Key(0, ui.KeyEnter)
if len(clicked) != 1 || clicked[0] != "fmt" {
t.Fatalf("clicked %v, want [fmt]", clicked)
}
}