From 5d512d4a28853702acb259a27c3704b1054d026a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Mon, 5 Oct 2026 12:25:27 -0400 Subject: [PATCH] Overlays: components 081-090 --- alert_dialog.go | 110 +++++ alert_dialog_test.go | 102 ++++ context_menu.go | 58 +++ context_menu_test.go | 105 ++++ dialog.go | 153 ++++++ dialog_test.go | 180 +++++++ docs/components/081-dialog.md | 75 +++ docs/components/082-alert-dialog.md | 65 +++ docs/components/083-drawer.md | 55 +++ docs/components/084-popover.md | 54 ++ docs/components/085-tooltip.md | 45 ++ docs/components/086-hover-card.md | 52 ++ docs/components/087-dropdown-menu.md | 75 +++ docs/components/088-context-menu.md | 55 +++ docs/components/089-popconfirm.md | 59 +++ docs/components/090-overlay.md | 51 ++ drawer.go | 151 ++++++ drawer_test.go | 129 +++++ dropdown_menu.go | 44 ++ dropdown_menu_test.go | 159 ++++++ example_overlay_test.go | 167 +++++++ examples/gallery/pages_overlay.go | 464 +++++++++++++++++- hover_card.go | 137 ++++++ hover_card_test.go | 117 +++++ messages_overlay.go | 13 + overlay.go | 181 +++++++ overlay_test.go | 201 ++++++++ popconfirm.go | 91 ++++ popconfirm_test.go | 70 +++ popover.go | 60 +++ popover_test.go | 102 ++++ popup_menu.go | 245 +++++++++ .../snapshots/darwin/alert_dialog-dark.png | Bin 0 -> 18244 bytes .../snapshots/darwin/alert_dialog-light.png | Bin 0 -> 19465 bytes .../snapshots/darwin/context_menu-dark.png | Bin 0 -> 12391 bytes .../snapshots/darwin/context_menu-light.png | Bin 0 -> 13791 bytes .../darwin/dialog-comfortable-dark.png | Bin 0 -> 18333 bytes .../darwin/dialog-comfortable-light.png | Bin 0 -> 19521 bytes .../snapshots/darwin/dialog-compact-dark.png | Bin 0 -> 16963 bytes .../snapshots/darwin/dialog-compact-light.png | Bin 0 -> 18379 bytes testdata/snapshots/darwin/dialog-dark.png | Bin 0 -> 17834 bytes testdata/snapshots/darwin/dialog-light.png | Bin 0 -> 19044 bytes testdata/snapshots/darwin/drawer-dark.png | Bin 0 -> 16085 bytes testdata/snapshots/darwin/drawer-light.png | Bin 0 -> 16230 bytes .../snapshots/darwin/dropdown_menu-dark.png | Bin 0 -> 11343 bytes .../snapshots/darwin/dropdown_menu-light.png | Bin 0 -> 12878 bytes testdata/snapshots/darwin/hover_card-dark.png | Bin 0 -> 11983 bytes .../snapshots/darwin/hover_card-light.png | Bin 0 -> 13494 bytes testdata/snapshots/darwin/overlay-dark.png | Bin 0 -> 9729 bytes testdata/snapshots/darwin/overlay-light.png | Bin 0 -> 10907 bytes testdata/snapshots/darwin/popconfirm-dark.png | Bin 0 -> 14906 bytes .../snapshots/darwin/popconfirm-light.png | Bin 0 -> 16285 bytes testdata/snapshots/darwin/popover-dark.png | Bin 0 -> 10984 bytes testdata/snapshots/darwin/popover-light.png | Bin 0 -> 12472 bytes testdata/snapshots/darwin/tooltip-dark.png | Bin 0 -> 4404 bytes testdata/snapshots/darwin/tooltip-light.png | Bin 0 -> 4513 bytes tooltip.go | 86 ++++ tooltip_test.go | 91 ++++ 58 files changed, 3801 insertions(+), 1 deletion(-) create mode 100644 alert_dialog.go create mode 100644 alert_dialog_test.go create mode 100644 context_menu.go create mode 100644 context_menu_test.go create mode 100644 dialog.go create mode 100644 dialog_test.go create mode 100644 docs/components/081-dialog.md create mode 100644 docs/components/082-alert-dialog.md create mode 100644 docs/components/083-drawer.md create mode 100644 docs/components/084-popover.md create mode 100644 docs/components/085-tooltip.md create mode 100644 docs/components/086-hover-card.md create mode 100644 docs/components/087-dropdown-menu.md create mode 100644 docs/components/088-context-menu.md create mode 100644 docs/components/089-popconfirm.md create mode 100644 docs/components/090-overlay.md create mode 100644 drawer.go create mode 100644 drawer_test.go create mode 100644 dropdown_menu.go create mode 100644 dropdown_menu_test.go create mode 100644 example_overlay_test.go create mode 100644 hover_card.go create mode 100644 hover_card_test.go create mode 100644 messages_overlay.go create mode 100644 overlay.go create mode 100644 overlay_test.go create mode 100644 popconfirm.go create mode 100644 popconfirm_test.go create mode 100644 popover.go create mode 100644 popover_test.go create mode 100644 popup_menu.go create mode 100644 testdata/snapshots/darwin/alert_dialog-dark.png create mode 100644 testdata/snapshots/darwin/alert_dialog-light.png create mode 100644 testdata/snapshots/darwin/context_menu-dark.png create mode 100644 testdata/snapshots/darwin/context_menu-light.png create mode 100644 testdata/snapshots/darwin/dialog-comfortable-dark.png create mode 100644 testdata/snapshots/darwin/dialog-comfortable-light.png create mode 100644 testdata/snapshots/darwin/dialog-compact-dark.png create mode 100644 testdata/snapshots/darwin/dialog-compact-light.png create mode 100644 testdata/snapshots/darwin/dialog-dark.png create mode 100644 testdata/snapshots/darwin/dialog-light.png create mode 100644 testdata/snapshots/darwin/drawer-dark.png create mode 100644 testdata/snapshots/darwin/drawer-light.png create mode 100644 testdata/snapshots/darwin/dropdown_menu-dark.png create mode 100644 testdata/snapshots/darwin/dropdown_menu-light.png create mode 100644 testdata/snapshots/darwin/hover_card-dark.png create mode 100644 testdata/snapshots/darwin/hover_card-light.png create mode 100644 testdata/snapshots/darwin/overlay-dark.png create mode 100644 testdata/snapshots/darwin/overlay-light.png create mode 100644 testdata/snapshots/darwin/popconfirm-dark.png create mode 100644 testdata/snapshots/darwin/popconfirm-light.png create mode 100644 testdata/snapshots/darwin/popover-dark.png create mode 100644 testdata/snapshots/darwin/popover-light.png create mode 100644 testdata/snapshots/darwin/tooltip-dark.png create mode 100644 testdata/snapshots/darwin/tooltip-light.png create mode 100644 tooltip.go create mode 100644 tooltip_test.go diff --git a/alert_dialog.go b/alert_dialog.go new file mode 100644 index 0000000..1f619d1 --- /dev/null +++ b/alert_dialog.go @@ -0,0 +1,110 @@ +package mujica + +import ( + "fmt" + "log/slog" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/internal" + "mujicaui/theme" +) + +// AlertDialogOptions configure an AlertDialog. Title is required. +type AlertDialogOptions struct { + Title string + Description string + // ConfirmLabel is "Delete" when empty; CancelLabel is "Cancel". + ConfirmLabel string + CancelLabel string + // ConfirmText, when set, must be typed before Confirm unlocks. + ConfirmText string +} + +// AlertDialogResult reports the choice made in this frame. +type AlertDialogResult struct { + Confirmed bool + Cancelled bool +} + +// alertDialogState is the typed confirmation, kept while the alert shows. +type alertDialogState struct{ typed string } + +// AlertDialog asks to confirm a destructive action while *open is true. +// Cancel takes the focus, the backdrop ignores clicks, Escape cancels, +// and Enter never confirms before ConfirmText is typed. +func AlertDialog(c *ui.Context, open *bool, opts AlertDialogOptions) AlertDialogResult { + if opts.Title == "" { + panic("mujica: AlertDialog needs a Title") + } + var res AlertDialogResult + if !*open { + return res + } + k := Tokens(c) + u := Density(c).Unit() + confirmLabel, cancelLabel := opts.ConfirmLabel, opts.CancelLabel + if confirmLabel == "" { + confirmLabel = msg(c, "alert_dialog.confirm") + } + if cancelLabel == "" { + cancelLabel = msg(c, "alert_dialog.cancel") + } + shown, backClicked := true, false + ui.DialogBase(c, &shown, func(back, panel *ui.Element) { + backClicked = back.Clicked() + st := ui.Local(panel, "mujica.alert", func() alertDialogState { return alertDialogState{} }) + p := overlayEnter(c, panel) + back.Background(overlayScrim(k).Alpha(p)).Padding(16) + dialogPanel(c, panel, 420, false, p) + panel.Role(ui.RoleAlertDialog).Label(opts.Title).Description(opts.Description) + ui.Row(c).Gap(u * 3).AlignItems(ui.Start).Shrink(0).Children(func() { + ui.Icon(c, icons.Must("triangle-alert")).Size(22, 22).TextColor(k.Danger).Shrink(0).Margin(1, 0, 0, 0) + ui.Column(c).Gap(u * 2).Grow(1).Children(func() { + ui.Text(c, opts.Title).Font(theme.SerifFont).FontSize(theme.H3Size).FontWeight(600) + if opts.Description != "" { + ui.Text(c, opts.Description).TextColor(k.TextMuted) + } + }) + }) + submitted := opts.ConfirmText != "" && alertDialogTyped(c, st, opts.ConfirmText) + unlocked := opts.ConfirmText == "" || st.typed == opts.ConfirmText + res.Confirmed = submitted && unlocked + dialogActions(c, func() { + if Button(c, cancelLabel, ButtonOptions{Variant: Secondary}).AutoFocus().Clicked() { + res.Cancelled = true + } + if Button(c, confirmLabel, ButtonOptions{Variant: Danger, Disabled: !unlocked}).Clicked() { + res.Confirmed = true + } + }) + }) + if !shown && !backClicked { + res.Cancelled = true // Escape + } + if res.Confirmed { + res.Cancelled = false + } + if res.Confirmed || res.Cancelled { + slog.Debug("mujica: alert_dialog close", "confirmed", res.Confirmed) + *open = false + } + return res +} + +// alertDialogTyped builds the confirmation field and reports Enter in it. +func alertDialogTyped(c *ui.Context, st *alertDialogState, want string) bool { + k := Tokens(c) + d := Density(c) + prompt := fmt.Sprintf(msg(c, "alert_dialog.type_to_unlock"), want) + submitted := false + ui.Column(c).Gap(d.Unit()).Shrink(0).Children(func() { + ui.Text(c, prompt).FontSize(theme.CaptionSize).TextColor(k.TextMuted) + in := ui.TextInputBase(c, &st.typed).Label(prompt).MinHeight(d.ControlHeight()).Padding(0, d.Unit()*3). + Radius(theme.ControlRadius).Background(k.Surface).Border(theme.BorderWidth, k.ControlBorder) + internal.Ring(in, k.Focus, theme.ControlRadius) + submitted = in.Submitted() + }) + return submitted +} diff --git a/alert_dialog_test.go b/alert_dialog_test.go new file mode 100644 index 0000000..0d23111 --- /dev/null +++ b/alert_dialog_test.go @@ -0,0 +1,102 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +type alertApp struct { + open bool + opts AlertDialogOptions + confirmed, cancelled int +} + +func (a *alertApp) view(c *ui.Context) { + Use(c, Settings{}) + if Button(c, "Remove", ButtonOptions{}).Clicked() { + a.open = true + } + r := AlertDialog(c, &a.open, a.opts) + if r.Confirmed { + a.confirmed++ + } + if r.Cancelled { + a.cancelled++ + } +} + +func newAlertApp(opts AlertDialogOptions) (*alertApp, *ui.Tester) { + opts.Title = "Delete the archive?" + a := &alertApp{opts: opts} + tt := ui.NewTester(a.view, 600, 400) + _ = tt.Click("Remove") + return a, tt +} + +func TestAlertDialogFocusesCancelAndEnterCancels(t *testing.T) { + a, tt := newAlertApp(AlertDialogOptions{Description: "This cannot be undone."}) + if !a.open || !tt.Focused("Cancel") { + t.Fatalf("open %v, Cancel focused %v", a.open, tt.Focused("Cancel")) + } + tt.Key(0, ui.KeyEnter) + if a.confirmed != 0 || a.cancelled != 1 || a.open { + t.Fatalf("Enter: confirmed %d cancelled %d open %v", a.confirmed, a.cancelled, a.open) + } + if !tt.Focused("Remove") { + t.Fatal("focus not restored") + } +} + +func TestAlertDialogIgnoresBackdropEscapeCancels(t *testing.T) { + a, tt := newAlertApp(AlertDialogOptions{}) + tt.ClickAt(8, 392) + if !a.open || a.cancelled != 0 { + t.Fatalf("backdrop click: open %v cancelled %d", a.open, a.cancelled) + } + tt.Key(0, ui.KeyEscape) + if a.open || a.cancelled != 1 || a.confirmed != 0 { + t.Fatalf("Escape: open %v cancelled %d confirmed %d", a.open, a.cancelled, a.confirmed) + } +} + +func TestAlertDialogConfirmOnce(t *testing.T) { + a, tt := newAlertApp(AlertDialogOptions{ConfirmLabel: "Erase"}) + if err := tt.Click("Erase"); err != nil { + t.Fatal(err) + } + if a.confirmed != 1 || a.cancelled != 0 || a.open { + t.Fatalf("confirmed %d cancelled %d open %v", a.confirmed, a.cancelled, a.open) + } +} + +func TestAlertDialogConfirmTextGatesEnter(t *testing.T) { + a, tt := newAlertApp(AlertDialogOptions{ConfirmText: "archive"}) + _ = tt.Click("Delete") // locked + if a.confirmed != 0 || !a.open { + t.Fatal("locked Delete confirmed") + } + if err := tt.Click("Type “archive” to confirm"); err != nil { + t.Fatal(err) + } + tt.Type("archiv") + tt.Key(0, ui.KeyEnter) + if a.confirmed != 0 || !a.open { + t.Fatalf("before the target matched: confirmed %d open %v", a.confirmed, a.open) + } + tt.Type("e") + tt.Key(0, ui.KeyEnter) + if a.confirmed != 1 || a.open { + t.Fatalf("typed target: confirmed %d open %v", a.confirmed, a.open) + } +} + +func TestAlertDialogSnapshot(t *testing.T) { + snapshot(t, "alert_dialog", 560, 320, func(c *ui.Context) { + open := true + AlertDialog(c, &open, AlertDialogOptions{ + Title: "Burn the old letters?", Description: "Twelve letters will be destroyed. This cannot be undone.", + ConfirmText: "letters", + }) + }) +} diff --git a/context_menu.go b/context_menu.go new file mode 100644 index 0000000..468029c --- /dev/null +++ b/context_menu.go @@ -0,0 +1,58 @@ +package mujica + +import ( + "log/slog" + + "github.com/egoist/mygo/ui" +) + +// ContextMenuOptions configure a ContextMenu. +type ContextMenuOptions struct { + Disabled bool +} + +// contextMenuState is where the menu opened, relative to the target. +type contextMenuState struct { + open bool + x, y float32 +} + +// ContextMenu gives target an in-window menu that build fills. A secondary +// click opens it at the pointer; the menu key or Shift+F10, while the focus +// is in target, opens it below target. It flips to stay in the window, and +// the focus returns on close. target must be a container: the menu adds an +// anchor child to it, and takes its HandleInput. It returns target. +func ContextMenu(c *ui.Context, target *ui.Element, opts ContextMenuOptions, build func(m *PopupMenu)) *ui.Element { + if target == nil { + panic("mujica: ContextMenu needs a target") + } + if build == nil { + panic("mujica: ContextMenu needs a build function") + } + st := ui.Local(target, "mujica.contextmenu", func() contextMenuState { return contextMenuState{} }) + if opts.Disabled { + st.open = false + return target + } + target.HandleInput(func(ev ui.InputEvent) bool { + if ev.Kind != ui.InputPointerDown || ev.Button != 1 { + return false + } + st.open, st.x, st.y = true, ev.X, ev.Y + slog.Debug("mujica: context_menu open", "by", "pointer") + return true + }) + if target.Shortcut(0, ui.KeyContextMenu) || target.Shortcut(ui.Shift, ui.KeyF10) { + st.open, st.x, st.y = true, 0, target.Bounds().H + slog.Debug("mujica: context_menu open", "by", "keyboard") + } + if !st.open { + return target + } + var anchor *ui.Element + target.Children(func() { + anchor = ui.Box(c).Key("mujica.contextmenu.anchor").Absolute().Left(st.x).Top(st.y).Size(1, 1).PassThrough() + }) + popupMenuOpen(c, anchor, &st.open, build) + return target +} diff --git a/context_menu_test.go b/context_menu_test.go new file mode 100644 index 0000000..c14c3c1 --- /dev/null +++ b/context_menu_test.go @@ -0,0 +1,105 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +func contextMenuTester(a *menuApp, disabled bool) *ui.Tester { + return ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Padding(20).Gap(8).Children(func() { + row := ui.Row(c).Height(80).FillWidth().Padding(12).Background(Tokens(c).Surface) + row.Children(func() { + Button(c, "Letter row", ButtonOptions{Variant: Ghost}) + }) + ContextMenu(c, row, ContextMenuOptions{Disabled: disabled}, a.build) + }) + }, 500, 320) +} + +func TestContextMenuOpensAtPointer(t *testing.T) { + a := &menuApp{} + tt := contextMenuTester(a, false) + tt.RightClickAt(200, 60) + tt.Frame() + r, ok := tt.Find("Rename") + // The label sits past the menu padding and the check column. + if !ok || r.X < 230 || r.X > 250 || r.Y < 60 || r.Y > 110 { + t.Fatalf("menu item %+v not at the pointer (200, 60)", r) + } + if tt.Menu() != nil { + t.Fatal("the system menu opened") + } + _ = tt.Click("Rename") + if len(a.chosen) != 1 || tt.HasText("Rename") { + t.Fatalf("chosen %q", a.chosen) + } +} + +func TestContextMenuOnInnerButtonAndEdge(t *testing.T) { + a := &menuApp{} + tt := contextMenuTester(a, false) + b, _ := tt.Find("Letter row") + tt.RightClickAt(b.X+4, b.Y+4) + if !tt.HasText("Rename") { + t.Fatal("right click on an inner button did not open the menu") + } + tt.Key(0, ui.KeyEscape) + tt.RightClickAt(480, 95) + tt.Frame() + last, _ := tt.Find("Burn") + first, _ := tt.Find("Rename") + if last.Y+last.H > 320 || first.Y > 95 || last.X+last.W > 500 { + t.Fatalf("menu not kept in the window: first %+v last %+v", first, last) + } +} + +func TestContextMenuKeyboard(t *testing.T) { + for _, key := range []struct { + mods ui.Modifiers + key ui.Key + }{{0, ui.KeyContextMenu}, {ui.Shift, ui.KeyF10}} { + a := &menuApp{} + tt := contextMenuTester(a, false) + tt.Key(0, ui.KeyTab) + tt.Key(key.mods, key.key) + tt.Frame() + if !tt.Focused("Rename") { + t.Fatalf("%v: menu did not open with focus", key) + } + item, _ := tt.Find("Rename") + if item.Y < 100 { + t.Fatalf("%v: keyboard menu %+v not below the focused target", key, item) + } + tt.Key(0, ui.KeyEscape) + if tt.HasText("Rename") || !tt.Focused("Letter row") { + t.Fatalf("%v: Escape did not close and restore", key) + } + } +} + +func TestContextMenuDisabled(t *testing.T) { + a := &menuApp{} + tt := contextMenuTester(a, true) + tt.RightClickAt(200, 60) + tt.Key(0, ui.KeyTab) + tt.Key(ui.Shift, ui.KeyF10) + if tt.HasText("Rename") { + t.Fatal("disabled context menu opened") + } +} + +func TestContextMenuSnapshot(t *testing.T) { + snapshot(t, "context_menu", 460, 320, func(c *ui.Context) { + a := &menuApp{} + ui.Column(c).Padding(20).Children(func() { + row := ui.Row(c).Height(36).FillWidth().Padding(0, 12).AlignItems(ui.Center).Background(Tokens(c).Selection) + row.Children(func() { ui.Text(c, "Letter to the Countess") }) + anchor := ui.Box(c).Absolute().Left(140).Top(48).Size(1, 1) + open := true + popupMenuOpen(c, anchor, &open, a.build) + }) + }) +} diff --git a/dialog.go b/dialog.go new file mode 100644 index 0000000..486e4f1 --- /dev/null +++ b/dialog.go @@ -0,0 +1,153 @@ +package mujica + +import ( + "log/slog" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/internal" + "mujicaui/theme" +) + +// DialogOptions configure a Dialog. Title is required. +type DialogOptions struct { + Title string + Description string + // Width is 440 DIPs when zero; the window always bounds it. + Width float32 + // Decorated draws the double border, corner ornaments and title rule. + Decorated bool + // Actions builds the footer, usually buttons, aligned to the end. + Actions func() + // KeepOnBackdrop ignores clicks on the backdrop. + KeepOnBackdrop bool + // KeepOnEscape ignores Escape. + KeepOnEscape bool + // HideClose removes the close button from the header. + HideClose bool +} + +// Dialog shows a modal dialog while *open is true. It traps the focus, +// makes the window inert and gives the focus back to the opener on close. +func Dialog(c *ui.Context, open *bool, opts DialogOptions, content func()) *ui.Element { + if opts.Title == "" { + panic("mujica: Dialog needs a Title") + } + if !*open { + return nil + } + k := Tokens(c) + shown, backClicked, closed := true, false, false + panel := ui.DialogBase(c, &shown, func(back, panel *ui.Element) { + backClicked = back.Clicked() + p := overlayEnter(c, panel) + back.Background(overlayScrim(k).Alpha(p)).Padding(16) + dialogPanel(c, panel, opts.Width, opts.Decorated, p) + panel.Label(opts.Title) + if opts.Description != "" { + panel.Description(opts.Description) + } + closed = dialogHeader(c, opts.Title, opts.Description, opts.Decorated, !opts.HideClose, "dialog.close") + if content != nil { + ui.Scroll(c).Shrink(1).Children(content) + } + if opts.Actions != nil { + dialogActions(c, opts.Actions) + } + }) + switch { + case closed: + slog.Debug("mujica: dialog close", "by", "button") + *open = false + case !shown && backClicked && !opts.KeepOnBackdrop: + slog.Debug("mujica: dialog close", "by", "backdrop") + *open = false + case !shown && !backClicked && !opts.KeepOnEscape: + slog.Debug("mujica: dialog close", "by", "escape") + *open = false + } + return panel +} + +// dialogPanel styles a centered dialog panel at entrance progress p. +func dialogPanel(c *ui.Context, panel *ui.Element, width float32, decorated bool, p float32) { + k := Tokens(c) + u := Density(c).Unit() + if width == 0 { + width = 440 + } + w, h := c.Size() + overlayStyle(c, panel, p) + panel.Width(width).MaxWidth(w-32).MaxHeight(h-32).Padding(u*6).Gap(u*3).Margin(8*(1-p), 0, 0, 0) + if decorated { + panel.Border(theme.BorderWidth, k.Ornament).Padding(u*6 + 6).DrawOver(func(pt *ui.Painter, r ui.Rect) { + dialogOrnaments(pt, r, k.Ornament, k.Surface) + }) + } +} + +// dialogOrnaments draws the inner frame and the four corner diamonds. +func dialogOrnaments(p *ui.Painter, r ui.Rect, ink, ground ui.Color) { + const in = 5 + f := ui.Rect{X: r.X + in, Y: r.Y + in, W: r.W - 2*in, H: r.H - 2*in} + p.Stroke(f, ink, 1, 1) + for _, pt := range [4][2]float32{{f.X, f.Y}, {f.X + f.W, f.Y}, {f.X, f.Y + f.H}, {f.X + f.W, f.Y + f.H}} { + x, y := internal.Snap(p, pt[0]), internal.Snap(p, pt[1]) + p.FillPath(internal.Diamond(x, y, 11), ground) + p.FillPath(internal.Diamond(x, y, 7), ink) + } +} + +// dialogHeader builds the title, description and close button; it reports a close click. +func dialogHeader(c *ui.Context, title, description string, decorated, closable bool, closeKey string) bool { + k := Tokens(c) + u := Density(c).Unit() + clicked := false + ui.Column(c).Gap(u).Shrink(0).Children(func() { + ui.Row(c).Gap(u * 3).AlignItems(ui.Start).Children(func() { + ui.Text(c, title).Font(theme.SerifFont).FontSize(theme.H3Size).FontWeight(600).Grow(1) + if closable { + clicked = dialogCloseButton(c, msg(c, closeKey)).Clicked() + } + }) + if decorated { + dialogRule(c, k.Ornament) + } + if description != "" { + ui.Text(c, description).TextColor(k.TextMuted) + } + }) + return clicked +} + +// dialogRule is the ornament line under a decorated title. +func dialogRule(c *ui.Context, ink ui.Color) { + ui.Box(c).FillWidth().Height(9).Margin(2, 0, 2, 0).Draw(func(p *ui.Painter, r ui.Rect) { + y, cx := r.Y+r.H/2, r.X+r.W/2 + p.Line(r.X, y, cx-10, y, 1, ink) + p.Line(cx+10, y, r.X+r.W, y, 1, ink) + p.FillPath(internal.Diamond(internal.Snap(p, cx), internal.Snap(p, y), 7), ink) + }) +} + +// dialogCloseButton is the 28 DIP icon button closing a panel. +func dialogCloseButton(c *ui.Context, label string) *ui.Element { + k := Tokens(c) + b := ui.ButtonBase(c).Size(theme.MinHitSize, theme.MinHitSize).Radius(theme.ControlRadius).Label(label).Margin(-4, -4, 0, 0) + internal.Ring(b, k.Focus, theme.ControlRadius) + b.TextColor(k.TextMuted) + if b.Pressed() { + b.Background(k.Selection).TextColor(k.Text) + } else if b.Hovered() { + b.Background(k.SurfaceHover).TextColor(k.Text) + } + b.Children(func() { ui.Icon(c, icons.Must("x")).Size(16, 16) }) + return b +} + +// dialogActions lays out a dialog footer. +func dialogActions(c *ui.Context, actions func()) { + u := Density(c).Unit() + ui.Row(c).Gap(u*2).Justify(ui.End).Wrap().Shrink(0).Margin(u*2, 0, 0, 0).Children(actions) +} diff --git a/dialog_test.go b/dialog_test.go new file mode 100644 index 0000000..3706ea7 --- /dev/null +++ b/dialog_test.go @@ -0,0 +1,180 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" + + "mujicaui/theme" +) + +type dialogApp struct { + open bool + opts DialogOptions + saved int + name string + densities theme.Density +} + +func (a *dialogApp) view(c *ui.Context) { + Use(c, Settings{Mode: Light, Density: a.densities}) + if Button(c, "Rename", ButtonOptions{}).Clicked() { + a.open = true + } + a.opts.Actions = func() { + if Button(c, "Cancel", ButtonOptions{Variant: Secondary}).Clicked() { + a.open = false + } + if Button(c, "Save", ButtonOptions{}).Clicked() { + a.saved++ + a.open = false + } + } + Dialog(c, &a.open, a.opts, func() { + ui.TextInput(c, &a.name) + }) +} + +func newDialogApp(opts DialogOptions) (*dialogApp, *ui.Tester) { + opts.Title = "Rename" + a := &dialogApp{opts: opts} + tt := ui.NewTester(a.view, 600, 400) + tt.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1}) + return a, tt +} + +func TestDialogOpenFocusTrapRestore(t *testing.T) { + a, tt := newDialogApp(DialogOptions{Description: "Pick a new name."}) + if err := tt.Click("Rename"); err != nil { + t.Fatal(err) + } + if !a.open || !tt.HasText("Pick a new name.") { + t.Fatalf("open %v, texts %q", a.open, tt.Texts()) + } + if !tt.Focused("Close") { + t.Fatalf("focus did not move into the dialog") + } + // Tab cycles Close, input, Cancel, Save and back to Close. + for range 3 { + tt.Key(0, ui.KeyTab) + } + if !tt.Focused("Save") { + t.Fatalf("tab order left the dialog") + } + tt.Key(0, ui.KeyTab) + if !tt.Focused("Close") { + t.Fatalf("tab did not wrap inside the dialog") + } + tt.Key(0, ui.KeyEscape) + if a.open { + t.Fatal("Escape did not close") + } + if !tt.Focused("Rename") { + t.Fatal("focus not restored to the opener") + } +} + +func TestDialogActionsAndClose(t *testing.T) { + a, tt := newDialogApp(DialogOptions{}) + _ = tt.Click("Rename") + if err := tt.Click("Save"); err != nil { + t.Fatal(err) + } + if a.saved != 1 || a.open { + t.Fatalf("saved %d open %v", a.saved, a.open) + } + _ = tt.Click("Rename") + if err := tt.Click("Close"); err != nil { + t.Fatal(err) + } + if a.open || a.saved != 1 { + t.Fatalf("close button: open %v saved %d", a.open, a.saved) + } +} + +func TestDialogCloseRules(t *testing.T) { + a, tt := newDialogApp(DialogOptions{}) + _ = tt.Click("Rename") + tt.ClickAt(10, 390) + if a.open { + t.Fatal("backdrop click did not close") + } + a, tt = newDialogApp(DialogOptions{KeepOnBackdrop: true, KeepOnEscape: true, HideClose: true}) + _ = tt.Click("Rename") + tt.ClickAt(10, 390) + tt.Key(0, ui.KeyEscape) + if !a.open { + t.Fatal("kept dialog closed") + } + if tt.HasText("Close") { + t.Fatal("close button shown with HideClose") + } + if _, ok := tt.Find("Close"); ok { + t.Fatal("close button present with HideClose") + } +} + +func TestDialogEscapeGoesToNestedPopoverFirst(t *testing.T) { + open, inner := true, false + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + Dialog(c, &open, DialogOptions{Title: "Outer"}, func() { + b := Button(c, "More", ButtonOptions{}) + if b.Clicked() { + inner = true + } + Popover(c, b, &inner, PopoverOptions{}, func() { ui.Text(c, "Inner") }) + }) + }, 600, 400) + _ = tt.Click("More") + if !inner { + t.Fatal("popover did not open") + } + tt.Key(0, ui.KeyEscape) + if inner || !open { + t.Fatalf("after one Escape inner %v outer %v", inner, open) + } + tt.Key(0, ui.KeyEscape) + if open { + t.Fatal("second Escape did not close the dialog") + } +} + +func TestDialogNeedsTitle(t *testing.T) { + defer func() { + if recover() == nil { + t.Fatal("no panic") + } + }() + open := true + ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + Dialog(c, &open, DialogOptions{}, nil) + }, 300, 200) +} + +func dialogSnapshotView(d theme.Density, decorated bool) func(c *ui.Context) { + return func(c *ui.Context) { + mode := Light + if Tokens(c).Dark { + mode = Dark + } + Use(c, Settings{Mode: mode, Density: d}) + open := true + name := "Ophelia" + ui.Column(c).Padding(24).Children(func() { ui.Text(c, "Behind the dialog") }) + Dialog(c, &open, DialogOptions{ + Title: "Rename the chamber", Description: "The new name shows in every hall.", Decorated: decorated, + Actions: func() { + Button(c, "Cancel", ButtonOptions{Variant: Secondary}) + Button(c, "Rename", ButtonOptions{}) + }, + }, func() { ui.TextInput(c, &name) }) + } +} + +func TestDialogSnapshot(t *testing.T) { + snapshot(t, "dialog", 560, 360, dialogSnapshotView(theme.Default, true)) + snapshot(t, "dialog-compact", 560, 360, dialogSnapshotView(theme.Compact, false)) + snapshot(t, "dialog-comfortable", 560, 400, dialogSnapshotView(theme.Comfortable, true)) +} diff --git a/docs/components/081-dialog.md b/docs/components/081-dialog.md new file mode 100644 index 0000000..679d06d --- /dev/null +++ b/docs/components/081-dialog.md @@ -0,0 +1,75 @@ +# 081 Dialog 对话框 + +## 用途 + +在窗口上方显示模态对话框:标题、说明、内容与操作区。打开时限制焦点并屏蔽背景,关闭后把焦点还给打开它的控件。视觉回归基准组件之一。 + +## 最小示例 + +```go +open := true +name := "Ophelia" +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.Button(c, "Rename…", mujica.ButtonOptions{}).Clicked() { + open = true + } + mujica.Dialog(c, &open, mujica.DialogOptions{ + Title: "Rename the chamber", + Description: "The new name shows in every hall.", + Decorated: true, + Actions: func() { + if mujica.Button(c, "Cancel", mujica.ButtonOptions{Variant: mujica.Secondary}).Clicked() { + open = false + } + if mujica.Button(c, "Rename", mujica.ButtonOptions{}).Clicked() { + open = false + } + }, + }, func() { + ui.TextInput(c, &name) + }) +} +ui.Render(view, 400, 300, 1) +``` + +签名:`func Dialog(c *ui.Context, open *bool, opts DialogOptions, content func()) *ui.Element`,关闭时返回 nil。 + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Title` | `string` | 必填 | 衬线标题,也是对话框的无障碍名称;为空时 panic。 | +| `Description` | `string` | `""` | 标题下的说明文字,同时作为无障碍描述。 | +| `Width` | `float32` | `440` | 面板宽度(DIP),始终不超过窗口宽度减 32。 | +| `Decorated` | `bool` | `false` | 开启双线边框、四角菱形角饰和标题下的装饰线。 | +| `Actions` | `func()` | `nil` | 页脚操作区,靠右排列,可换行。 | +| `KeepOnBackdrop` | `bool` | `false` | 点击遮罩不关闭。 | +| `KeepOnEscape` | `bool` | `false` | Escape 不关闭。 | +| `HideClose` | `bool` | `false` | 不显示右上角关闭按钮。 | + +`open` 为 false 时不构建任何元素。`content` 可为 nil;内容超出窗口高度时在内容区滚动。 + +## 状态 + +- 打开:遮罩渐入,面板 160 ms 淡入并上移 8 DIP;减少动画时直接显示。 +- 关闭按钮:悬停、按下、键盘焦点环(2 DIP,留 2 DIP 间隔)。 +- 装饰:只出现在边缘与标题区,不占焦点,不影响点击区域。 + +## 事件 + +- 关闭按钮、遮罩点击、Escape 把 `*open` 设为 false(各自可关闭)。 +- 业务事件由 `Actions` 和 `content` 中的控件自己报告。 + +## 键盘操作 + +| 按键 | 行为 | +| --- | --- | +| Tab / Shift+Tab | 在对话框内循环,不会离开。 | +| Escape | 先交给输入法与正在编辑的控件,再关闭最上层浮层;嵌套 Popover 或菜单先关。 | +| Enter / Space | 触发聚焦的按钮。 | + +## 限制 + +- 关闭后焦点回到打开时的控件;若该控件已不存在,MyGo 不回退到父级(`ui/scope.go:137` restoreFocus 只恢复原控件),焦点为空,再按 Tab 从窗口开头开始。 +- 没有关闭过渡:MyGo 在 `*open` 变为 false 的下一帧即移除浮层元素,`Transition` 的 Exit 需要父元素保留,而浮层根只在有浮层时存在。 diff --git a/docs/components/082-alert-dialog.md b/docs/components/082-alert-dialog.md new file mode 100644 index 0000000..40c2a18 --- /dev/null +++ b/docs/components/082-alert-dialog.md @@ -0,0 +1,65 @@ +# 082 AlertDialog 警示对话框 + +## 用途 + +确认危险操作。默认聚焦“取消”,点击遮罩无效,Escape 等同取消;可要求先输入目标名称,未确认目标前 Enter 不会执行。 + +## 最小示例 + +```go +open := true +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.Button(c, "Delete archive", mujica.ButtonOptions{Variant: mujica.Danger}).Clicked() { + open = true + } + r := mujica.AlertDialog(c, &open, mujica.AlertDialogOptions{ + Title: "Delete the archive?", + Description: "Twelve letters will be destroyed.", + ConfirmText: "archive", + }) + if r.Confirmed { + fmt.Println("deleted") + } +} +ui.Render(view, 400, 300, 1) +``` + +签名:`func AlertDialog(c *ui.Context, open *bool, opts AlertDialogOptions) AlertDialogResult`。 + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Title` | `string` | 必填 | 标题与无障碍名称;为空时 panic。 | +| `Description` | `string` | `""` | 后果说明,同时作为无障碍描述。 | +| `ConfirmLabel` | `string` | 内置“删除 / Delete” | 危险按钮文字。 | +| `CancelLabel` | `string` | 内置“取消 / Cancel” | 取消按钮文字。 | +| `ConfirmText` | `string` | `""` | 非空时显示输入框,输入内容与之完全相同后确认按钮才可用。 | + +`AlertDialogResult{Confirmed, Cancelled bool}` 只在发生选择的那一帧为 true,之后对话框关闭。 + +## 状态 + +- 确认按钮使用 Danger 变体;`ConfirmText` 未匹配时禁用(MyGo 统一变暗)。 +- 输入框有边框与焦点环;内容保留在对话框打开期间,关闭后清空。 + +## 事件 + +- `Confirmed`:点击确认,或在输入框内按 Enter 且目标已匹配。 +- `Cancelled`:点击取消、在取消上按 Enter / Space、或按 Escape。 +- 点击遮罩不产生事件。 + +## 键盘操作 + +| 按键 | 行为 | +| --- | --- | +| 打开时 | 焦点在“取消”。 | +| Enter | 触发聚焦的按钮;在输入框中只有目标匹配时确认。 | +| Escape | 取消并关闭。 | +| Tab | 在对话框内循环。 | + +## 限制 + +- 取消按钮的焦点由 `AutoFocus` 给出,打开时不显示焦点环(MyGo 只在键盘移动焦点后设置可见焦点,`ui/input.go:868`);按 Tab 后显示。 +- 不替代系统原生警示框;需要系统样式时用 MyGo 的桌面对话框。 diff --git a/docs/components/083-drawer.md b/docs/components/083-drawer.md new file mode 100644 index 0000000..dce31ee --- /dev/null +++ b/docs/components/083-drawer.md @@ -0,0 +1,55 @@ +# 083 Drawer 抽屉 + +## 用途 + +从窗口四边之一滑出的面板,用于筛选、详情和设置。可选模态或非模态。 + +## 最小示例 + +```go +open := true +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.Button(c, "Filters", mujica.ButtonOptions{}).Clicked() { + open = true + } + mujica.Drawer(c, &open, mujica.DrawerOptions{Title: "Filters", Side: mujica.DrawerRight, Size: 320}, func() { + ui.Text(c, "Guests are placed by rank.") + }) +} +ui.Render(view, 400, 300, 1) +``` + +签名:`func Drawer(c *ui.Context, open *bool, opts DrawerOptions, content func()) *ui.Element`。 + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Title` | `string` | 必填 | 标题与无障碍名称;为空时 panic。 | +| `Side` | `DrawerSide` | `DrawerRight` | `DrawerRight`、`DrawerLeft`、`DrawerTop`、`DrawerBottom`;越界时 panic。 | +| `Size` | `float32` | 左右 360,上下 280 | 宽度或高度;限制在 160 DIP 与窗口的 90% 之间;负数 panic。 | +| `NonModal` | `bool` | `false` | 非模态:不加遮罩、不限制焦点,窗口其余部分仍可操作。 | +| `Actions` | `func()` | `nil` | 页脚操作区。 | + +## 状态 + +- 打开时从所在边滑入并淡入 160 ms;减少动画时直接出现。 +- 面板贴边,只在朝内一侧画 1 DIP 分隔线。 +- 内容超出时在内容区滚动。 + +## 事件 + +关闭按钮与 Escape 把 `*open` 设为 false;模态抽屉点击遮罩同样关闭。 + +## 键盘操作 + +| 按键 | 行为 | +| --- | --- | +| Tab / Shift+Tab | 模态:在抽屉内循环。非模态:按窗口焦点顺序,抽屉内容排在窗口内容之后。 | +| Escape | 关闭(先交给正在编辑的控件和更上层浮层)。 | + +## 限制 + +- 非模态抽屉不在打开时移动焦点,关闭时也不自动恢复焦点:MyGo 记录与恢复打开者的 `openOverlay` 不公开(`ui/scope.go:123`),也没有读取当前焦点的公开接口。 +- 非模态抽屉的 Escape 是窗口级快捷键,优先级最低;同时打开多个非模态浮层时由先构建的那个响应。 diff --git a/docs/components/084-popover.md b/docs/components/084-popover.md new file mode 100644 index 0000000..a1cf618 --- /dev/null +++ b/docs/components/084-popover.md @@ -0,0 +1,54 @@ +# 084 Popover 弹出框 + +## 用途 + +在锚点下方显示可交互的面板;空间不足时翻到上方,并保持在窗口内。外部点击与 Escape 关闭。 + +## 最小示例 + +```go +open := true +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + b := mujica.Button(c, "Guests", mujica.ButtonOptions{Variant: mujica.Secondary}) + if b.Clicked() { + open = !open + } + mujica.Popover(c, b, &open, mujica.PopoverOptions{Title: "Guest list"}, func() { + ui.Text(c, "Twelve guests confirmed.") + }) +} +ui.Render(view, 400, 300, 1) +``` + +签名:`func Popover(c *ui.Context, anchor *ui.Element, open *bool, opts PopoverOptions, content func()) *ui.Element`。`anchor` 必须是本帧已构建的元素,nil 时 panic。 + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Title` | `string` | `""` | 面板顶部的衬线标题,同时命名面板。 | +| `Width` | `float32` | 0 | 固定宽度;0 时随内容,至少与锚点同宽,最多 360。 | +| `Label` | `string` | `""` | 无标题时的无障碍名称。 | + +## 状态 + +- 6 DIP 圆角、Surface 底色、1 DIP 边框、160 ms 淡入。 +- 面板最高为锚点上下较大一侧的空间,超出时滚动。 +- 锚点首帧尚未布局时面板保持透明,避免闪到窗口左上角。 + +## 事件 + +外部点击与 Escape 把 `*open` 设为 false;内容内控件自行报告事件。 + +## 键盘操作 + +| 按键 | 行为 | +| --- | --- | +| Tab | 从锚点进入弹层,弹层元素紧跟锚点排序。 | +| Escape | 关闭并把焦点还给锚点。 | + +## 限制 + +- 只支持下方与上方两个位置:位置由 MyGo `PopoverBase` 决定(`ui/widgets.go:689` keepInWindow)。 +- 打开时外部点击只用于关闭,不会传给下方控件:`PopoverBase` 用覆盖整窗的背板接收点击(`ui/base.go:373`)。 diff --git a/docs/components/085-tooltip.md b/docs/components/085-tooltip.md new file mode 100644 index 0000000..c3137b2 --- /dev/null +++ b/docs/components/085-tooltip.md @@ -0,0 +1,45 @@ +# 085 Tooltip 文字提示 + +## 用途 + +指针停留或键盘聚焦一段时间后,在元素旁显示简短说明。提示不含交互内容,不拦截指针,并作为元素的无障碍描述。 + +## 最小示例 + +```go +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + b := mujica.Button(c, "Seal", mujica.ButtonOptions{}) + mujica.Tooltip(c, b, "Seal the letter with wax", mujica.TooltipOptions{}) +} +ui.Render(view, 400, 300, 1) +``` + +签名:`func Tooltip(c *ui.Context, anchor *ui.Element, text string, opts TooltipOptions) *ui.Element`,返回 `anchor`。`anchor` 为 nil 时 panic;`text` 为空时什么也不做。 + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Delay` | `time.Duration` | 500 ms | 悬停或键盘聚焦持续多久后显示;负数 panic。 | + +## 状态 + +- 炭黑底(深色主题为象牙底)、2 DIP 圆角、12+1 DIP 文字,最宽 240 DIP 后换行。 +- 默认在元素下方居中,下方放不下时翻到上方,左右限制在窗口内。 + +## 事件 + +无业务事件。`text` 同时写入 `anchor` 的无障碍描述。 + +## 键盘操作 + +| 按键 | 行为 | +| --- | --- | +| Tab 聚焦 | 键盘焦点停留 `Delay` 后显示。 | +| Escape | 隐藏,直到指针离开或焦点移走。 | + +## 限制 + +- 只在键盘焦点(可见焦点)时显示,鼠标点击获得的焦点不触发,避免点击后弹出提示。 +- 不使用 MyGo 的 `Element.Tooltip`:它只跟随指针、不响应焦点(`ui/widgets.go:549`)。 diff --git a/docs/components/086-hover-card.md b/docs/components/086-hover-card.md new file mode 100644 index 0000000..18c1dc5 --- /dev/null +++ b/docs/components/086-hover-card.md @@ -0,0 +1,52 @@ +# 086 HoverCard 悬停卡片 + +## 用途 + +悬停或聚焦锚点时预览更多信息,例如人物资料。指针可以移入卡片并操作其中的控件,键盘可以 Tab 进入卡片,离开后延迟关闭。 + +## 最小示例 + +```go +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + b := mujica.Button(c, "Lady Sakiko", mujica.ButtonOptions{Variant: mujica.Ghost}) + mujica.HoverCard(c, b, mujica.HoverCardOptions{}, func() { + ui.Text(c, "Keyboardist of the court.") + }) +} +ui.Render(view, 400, 300, 1) +``` + +签名:`func HoverCard(c *ui.Context, anchor *ui.Element, opts HoverCardOptions, content func()) *ui.Element`,返回卡片,未显示时为 nil。 + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `OpenDelay` | `time.Duration` | 500 ms | 悬停或聚焦多久后打开;负数 panic。 | +| `CloseDelay` | `time.Duration` | 300 ms | 指针与焦点都离开后多久关闭;负数 panic。 | +| `Width` | `float32` | 280 | 卡片宽度。 | +| `Label` | `string` | `""` | 卡片的无障碍名称。 | + +## 状态 + +- 打开、关闭都按延迟进行;减少动画时取消淡入。 +- 指针在锚点或卡片上、或键盘焦点在锚点或卡片内时保持打开。 +- 下方空间不足时翻到上方,左右限制在窗口内。 + +## 事件 + +返回值由 nil 变为非 nil 即打开;卡片内控件自行报告事件。 + +## 键盘操作 + +| 按键 | 行为 | +| --- | --- | +| Tab 聚焦锚点 | `OpenDelay` 后打开。 | +| Tab | 从锚点进入卡片内的控件,再继续到后面的元素。 | +| Escape | 立即关闭,焦点回到锚点,直到焦点离开前不再打开。 | + +## 限制 + +- 键盘打开时卡片由 `PopoverBase` 承载,以便焦点顺序紧跟锚点;此时卡片外的点击只用于关闭(`ui/base.go:373`)。指针打开时卡片不拦截窗口其余部分。 +- 指针打开时卡片元素在窗口焦点顺序的末尾。 diff --git a/docs/components/087-dropdown-menu.md b/docs/components/087-dropdown-menu.md new file mode 100644 index 0000000..605c7a7 --- /dev/null +++ b/docs/components/087-dropdown-menu.md @@ -0,0 +1,75 @@ +# 087 DropdownMenu 下拉菜单 + +## 用途 + +按钮触发的应用内菜单,由 MujicaUI 自绘(不是系统菜单)。支持分组、子菜单、勾选项与禁用项;选择后按规则关闭。 + +## 最小示例 + +```go +pinned := false +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.DropdownMenu(c, "Actions", mujica.DropdownMenuOptions{}, func(m *mujica.PopupMenu) { + m.Group("Letter", func() { + if m.Item("Rename", mujica.PopupMenuItemOptions{}) { + fmt.Println("rename") + } + m.Check("Pinned", &pinned, mujica.PopupMenuItemOptions{KeepOpen: true}) + }) + m.Submenu("Move to", mujica.PopupMenuItemOptions{}, func(m *mujica.PopupMenu) { + m.Item("Archive", mujica.PopupMenuItemOptions{}) + }) + m.Separator() + m.Item("Burn", mujica.PopupMenuItemOptions{Disabled: true}) + }) +} +ui.Render(view, 400, 300, 1) +``` + +签名:`func DropdownMenu(c *ui.Context, label string, opts DropdownMenuOptions, build func(m *PopupMenu)) *ui.Element`,返回触发按钮。`build` 为 nil、或 `label` 与 `opts.Label` 都为空时 panic。 + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Icon` | `*ui.SVG` | `nil` | 标签前的图标。 | +| `Disabled` | `bool` | `false` | 禁用触发按钮并关闭已打开的菜单。 | +| `Label` | `string` | `""` | 仅图标按钮的无障碍名称。 | + +`PopupMenu` 方法: + +| 方法 | 说明 | +| --- | --- | +| `Item(label, opts) bool` | 普通项;本帧被选择时返回 true。 | +| `Check(label, *bool, opts) bool` | 勾选项,切换 `*bool`;本帧变化时返回 true。 | +| `Submenu(label, opts, build)` | 子菜单项;`build` 为 nil 时 panic。 | +| `Group(label, fn)` | 带说明文字的分组,前面有内容时自动加分隔线。 | +| `Separator()` | 分隔线。 | + +`PopupMenuItemOptions`:`Disabled bool`(不可选、不进入方向键序列),`KeepOpen bool`(选择后不关闭菜单)。 + +## 状态 + +- 触发按钮:次按钮外观加下拉箭头,打开时保持按下底色。 +- 菜单项:悬停或键盘焦点时显示 Selection 底色和左侧 2 DIP 强调条;勾选项显示勾号;禁用项变暗。 +- 菜单面板最高为可用空间,超出时滚动;子菜单在右侧打开,右侧放不下时翻到左侧,下方放不下时上移。 + +## 事件 + +`Item` / `Check` 的返回值;每次选择只报告一次。 + +## 键盘操作 + +| 按键 | 行为 | +| --- | --- | +| Enter / Space / ↓ | 在触发按钮上打开菜单,焦点在第一项。 | +| ↑ / ↓ / Home / End | 在当前层移动,跳过禁用项,首尾循环。 | +| → / Enter | 在子菜单项上打开子菜单并进入。 | +| ← / Escape | 在子菜单中关闭子菜单,回到父项。 | +| Escape / Tab | 关闭菜单,焦点回到触发按钮。 | + +## 限制 + +- MyGo 没有 menu / menuitem 无障碍角色(`ui/access.go:22` Role 列表),菜单面板报告为 popup,普通项为 button,勾选项为 checkbox,触发按钮为 menu button。 +- 菜单打开期间外部点击只用于关闭(`ui/base.go:373`)。 diff --git a/docs/components/088-context-menu.md b/docs/components/088-context-menu.md new file mode 100644 index 0000000..b37874d --- /dev/null +++ b/docs/components/088-context-menu.md @@ -0,0 +1,55 @@ +# 088 ContextMenu 右键菜单 + +## 用途 + +为一块区域提供应用内右键菜单,由 MujicaUI 自绘。右键在指针处打开,键盘在焦点区域下方打开,并避开窗口边缘。菜单项与 DropdownMenu 相同(`PopupMenu`)。 + +## 最小示例 + +```go +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + row := ui.Row(c).Padding(12).Children(func() { + ui.Text(c, "Letter to the Countess") + }) + mujica.ContextMenu(c, row, mujica.ContextMenuOptions{}, func(m *mujica.PopupMenu) { + if m.Item("Reply", mujica.PopupMenuItemOptions{}) { + fmt.Println("reply") + } + m.Item("Delete", mujica.PopupMenuItemOptions{}) + }) +} +ui.Render(view, 400, 300, 1) +``` + +签名:`func ContextMenu(c *ui.Context, target *ui.Element, opts ContextMenuOptions, build func(m *PopupMenu)) *ui.Element`,返回 `target`。`target` 或 `build` 为 nil 时 panic。 + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Disabled` | `bool` | `false` | 不响应右键与菜单键,并关闭已打开的菜单。 | + +`PopupMenu` 的方法与选项见 [087 DropdownMenu](087-dropdown-menu.md)。 + +## 状态 + +与 DropdownMenu 菜单面板相同。右下角附近打开时,菜单向左、向上翻转,保持在窗口内。 + +## 事件 + +`Item` / `Check` 的返回值;每次选择只报告一次。 + +## 键盘操作 + +| 按键 | 行为 | +| --- | --- | +| Menu 键 / Shift+F10 | 焦点在 `target` 内时,在 `target` 左下方打开,焦点在第一项。 | +| 菜单内按键 | 同 DropdownMenu。 | +| Escape | 关闭,焦点回到打开前的控件。 | + +## 限制 + +- `target` 必须是容器:菜单会向它追加一个不可见的定位子元素,文字元素不能有非文字子元素(MyGo 会 panic)。 +- 菜单通过 `target.HandleInput` 接收右键按下,因此会替换调用方在同一元素上设置的 `HandleInput`(MyGo 每个元素只保存一个处理函数,`ui/handler.go:73`)。 +- 不使用 MyGo 的 `Element.ContextMenu`:那是系统菜单,PRD 不允许把它当作哥特样式菜单。 diff --git a/docs/components/089-popconfirm.md b/docs/components/089-popconfirm.md new file mode 100644 index 0000000..7998d35 --- /dev/null +++ b/docs/components/089-popconfirm.md @@ -0,0 +1,59 @@ +# 089 Popconfirm 气泡确认 + +## 用途 + +在触发控件旁做轻量确认(归档、移出列表等可撤销操作)。说明与面板关联,确认与取消都可聚焦。高风险操作请用 AlertDialog。 + +## 最小示例 + +```go +open := false +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + b := mujica.Button(c, "Archive", mujica.ButtonOptions{Variant: mujica.Secondary}) + if b.Clicked() { + open = true + } + if mujica.Popconfirm(c, b, &open, mujica.PopconfirmOptions{Title: "Archive this letter?"}).Confirmed { + fmt.Println("archived") + } +} +ui.Render(view, 400, 300, 1) +``` + +签名:`func Popconfirm(c *ui.Context, anchor *ui.Element, open *bool, opts PopconfirmOptions) PopconfirmResult`。`anchor` 为 nil 或 `Title` 为空时 panic。 + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Title` | `string` | 必填 | 问题,也是面板的无障碍名称。 | +| `Description` | `string` | `""` | 补充说明,作为面板的无障碍描述。 | +| `ConfirmLabel` | `string` | 内置“确定 / Confirm” | 确认按钮文字。 | +| `CancelLabel` | `string` | 内置“取消 / Cancel” | 取消按钮文字。 | +| `Danger` | `bool` | `false` | 确认按钮使用危险变体,图标改为 Danger 色。 | + +`PopconfirmResult{Confirmed, Cancelled bool}` 只在发生选择的那一帧为 true。 + +## 状态 + +与 Popover 相同的面板;下方放不下时翻到上方。 + +## 事件 + +- `Confirmed`:点击确认或在其上按 Enter / Space。 +- `Cancelled`:点击取消、Escape、外部点击。 + +## 键盘操作 + +| 按键 | 行为 | +| --- | --- | +| 打开时 | 焦点在确认按钮。 | +| Enter | 触发聚焦的按钮。 | +| Tab | 在取消与确认间移动,焦点顺序紧跟锚点。 | +| Escape | 取消并把焦点还给锚点。 | + +## 限制 + +- 非模态:不屏蔽窗口,但外部点击只用于取消,不传给下方控件(`ui/base.go:373`)。 +- 位置只有下方与上方(`ui/widgets.go:689`)。 diff --git a/docs/components/090-overlay.md b/docs/components/090-overlay.md new file mode 100644 index 0000000..053a732 --- /dev/null +++ b/docs/components/090-overlay.md @@ -0,0 +1,51 @@ +# 090 Overlay 覆盖层 + +## 用途 + +在窗口内显示一层自定义内容:九个位置、可选遮罩、模态或非模态。模态时复用 MyGo `DialogBase` 的焦点限制与背景屏蔽,可与 MyGo 自带的 Select、Popover、菜单嵌套使用。 + +## 最小示例 + +```go +open := true +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.Overlay(c, &open, mujica.OverlayOptions{Place: mujica.OverlayBottomRight, Label: "Now playing"}, func() { + ui.Text(c, "Symbol I: △") + }) +} +ui.Render(view, 400, 300, 1) +``` + +签名:`func Overlay(c *ui.Context, open *bool, opts OverlayOptions, content func()) *ui.Element`。 + +## 参数 + +| 字段 | 类型 | 默认值 | 含义 | +| --- | --- | --- | --- | +| `Place` | `OverlayPlace` | `OverlayCenter` | `OverlayCenter`、`Top`、`Bottom`、`Left`、`Right`、`TopLeft`、`TopRight`、`BottomLeft`、`BottomRight`;越界 panic。 | +| `Inset` | `float32` | 16 | 面板与窗口边缘的距离。 | +| `Modal` | `bool` | `false` | 限制焦点、屏蔽背景,点击背景关闭。 | +| `Dim` | `bool` | `false` | 模态时加暗色遮罩;未开 `Modal` 时 panic。 | +| `Label` | `string` | `""` | 覆盖层的无障碍名称。 | + +## 状态 + +弹层外观(Surface 底、1 DIP 边框、6 DIP 圆角)与 160 ms 淡入;减少动画时直接显示。 + +## 事件 + +Escape 与(模态时)背景点击把 `*open` 设为 false。 + +## 键盘操作 + +| 按键 | 行为 | +| --- | --- | +| Escape | 关闭;先交给编辑中的控件和更上层浮层。 | +| Tab | 模态时在覆盖层内循环;非模态时覆盖层元素排在窗口焦点顺序末尾。 | + +## 限制 + +- 非模态覆盖层的 Escape 是窗口级快捷键(MyGo 浮层专用快捷键 `overlayShortcut` 不公开,`ui/scope.go:109`),同时打开多个非模态浮层时由先构建的那个响应。 +- 非模态覆盖层关闭时不自动恢复焦点(`ui/scope.go:123` openOverlay 不公开)。 +- 非模态面板首帧尚未测量尺寸,该帧透明,下一帧定位后淡入。 diff --git a/drawer.go b/drawer.go new file mode 100644 index 0000000..5897a86 --- /dev/null +++ b/drawer.go @@ -0,0 +1,151 @@ +package mujica + +import ( + "log/slog" + + "github.com/egoist/mygo/ui" + + "mujicaui/theme" +) + +// DrawerSide is the window edge a Drawer comes from. The zero value is DrawerRight. +type DrawerSide int + +const ( + DrawerRight DrawerSide = iota + DrawerLeft + DrawerTop + DrawerBottom +) + +// DrawerOptions configure a Drawer. Title is required. +type DrawerOptions struct { + Title string + Side DrawerSide + // Size is the width (left, right) or height (top, bottom): 360 or 280 DIPs when zero. + // It is kept between 160 DIPs and 90% of the window. + Size float32 + // NonModal leaves the window usable and the focus free. + NonModal bool + // Actions builds the footer, aligned to the end. + Actions func() +} + +// Drawer shows a panel along a window edge while *open is true. A modal +// drawer traps the focus and restores it on close; Escape closes either kind. +func Drawer(c *ui.Context, open *bool, opts DrawerOptions, content func()) *ui.Element { + if opts.Title == "" { + panic("mujica: Drawer needs a Title") + } + if opts.Side < DrawerRight || opts.Side > DrawerBottom { + panic("mujica: Drawer Side out of range") + } + if opts.Size < 0 { + panic("mujica: Drawer Size is negative") + } + if !*open { + return nil + } + k := Tokens(c) + size := drawerSize(c, opts) + closed := false + body := func(panel *ui.Element, p float32) { + drawerPanel(c, panel, opts.Side, size, p) + panel.Label(opts.Title) + closed = dialogHeader(c, opts.Title, "", false, true, "drawer.close") + if content != nil { + ui.Scroll(c).Grow(1).Shrink(1).Children(content) + } + if opts.Actions != nil { + dialogActions(c, opts.Actions) + } + } + var panel *ui.Element + escaped := false + if opts.NonModal { + ui.Overlay(c, func() { + panel = ui.Column(c).Absolute().Role(ui.RoleDialog) + p := overlayEnter(c, panel) + drawerPlace(c, panel, opts.Side, size*p) + panel.Children(func() { body(panel, p) }) + }) + escaped = c.Shortcut(0, ui.KeyEscape) + } else { + shown := true + panel = ui.DialogBase(c, &shown, func(back, panel *ui.Element) { + p := overlayEnter(c, panel) + back.Background(overlayScrim(k).Alpha(p)) + drawerBackdrop(back, opts.Side) + body(panel, p) + }) + escaped = !shown + } + if closed || escaped { + slog.Debug("mujica: drawer close", "escape", escaped) + *open = false + } + return panel +} + +func drawerSize(c *ui.Context, opts DrawerOptions) float32 { + w, h := c.Size() + extent, size := w, opts.Size + if opts.Side == DrawerTop || opts.Side == DrawerBottom { + extent = h + if size == 0 { + size = 280 + } + } else if size == 0 { + size = 360 + } + return max(min(size, extent*0.9), min(160, extent)) +} + +func drawerHorizontal(s DrawerSide) bool { return s == DrawerLeft || s == DrawerRight } + +// drawerBackdrop lines the panel up against its edge inside a modal backdrop. +func drawerBackdrop(back *ui.Element, s DrawerSide) { + if drawerHorizontal(s) { + back.Row() + } + back.AlignItems(ui.Stretch).Justify(ui.Start) + if s == DrawerRight || s == DrawerBottom { + back.Justify(ui.End) + } +} + +// drawerPlace puts a non-modal panel against its edge, shown by size. +func drawerPlace(c *ui.Context, panel *ui.Element, s DrawerSide, size float32) { + w, h := c.Size() + switch s { + case DrawerRight: + panel.Left(w - size).Top(0).Height(h) + case DrawerLeft: + panel.Left(0).Top(0).Height(h) + case DrawerTop: + panel.Left(0).Top(0).Width(w) + case DrawerBottom: + panel.Left(0).Top(h - size).Width(w) + } +} + +// drawerPanel styles the panel at entrance progress p, sliding in from its edge. +func drawerPanel(c *ui.Context, panel *ui.Element, s DrawerSide, size, p float32) { + k := Tokens(c) + u := Density(c).Unit() + off := -(1 - p) * size + panel.Background(k.Surface).TextColor(k.Text).Opacity(p).Padding(u*6).Gap(u*3). + Shadow(0, 0, 24, 0, ui.RGBA(0, 0, 0, 0.18*p)) + bw := theme.BorderWidth + switch s { + case DrawerRight: + panel.Width(size).BorderWidth(0, 0, 0, bw).Margin(0, off, 0, 0) + case DrawerLeft: + panel.Width(size).BorderWidth(0, bw, 0, 0).Margin(0, 0, 0, off) + case DrawerTop: + panel.Height(size).BorderWidth(0, 0, bw, 0).Margin(off, 0, 0, 0) + case DrawerBottom: + panel.Height(size).BorderWidth(bw, 0, 0, 0).Margin(0, 0, off, 0) + } + panel.BorderColor(k.Border) +} diff --git a/drawer_test.go b/drawer_test.go new file mode 100644 index 0000000..fdfa533 --- /dev/null +++ b/drawer_test.go @@ -0,0 +1,129 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +type drawerApp struct { + open bool + opts DrawerOptions + clicked int + panel ui.Rect +} + +func (a *drawerApp) view(c *ui.Context) { + Use(c, Settings{}) + ui.Row(c).Gap(8).Children(func() { + if Button(c, "Filters", ButtonOptions{}).Clicked() { + a.open = true + } + if Button(c, "Behind", ButtonOptions{}).Clicked() { + a.clicked++ + } + }) + if p := Drawer(c, &a.open, a.opts, func() { + Button(c, "Apply", ButtonOptions{}) + }); p != nil { + a.panel = p.Bounds() + } +} + +func newDrawerApp(opts DrawerOptions) (*drawerApp, *ui.Tester) { + opts.Title = "Filters panel" + a := &drawerApp{opts: opts} + tt := ui.NewTester(a.view, 800, 500) + tt.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1}) + _ = tt.Click("Filters") + tt.Frame() + return a, tt +} + +func TestDrawerSides(t *testing.T) { + for _, tc := range []struct { + side DrawerSide + x, y, w, h float32 + }{ + {DrawerRight, 440, 0, 360, 500}, + {DrawerLeft, 0, 0, 360, 500}, + {DrawerTop, 0, 0, 800, 280}, + {DrawerBottom, 0, 220, 800, 280}, + } { + for _, nonModal := range []bool{false, true} { + a, _ := newDrawerApp(DrawerOptions{Side: tc.side, NonModal: nonModal}) + got := a.panel + if got.X != tc.x || got.Y != tc.y || got.W != tc.w || got.H != tc.h { + t.Errorf("side %d nonModal %v: panel %+v", tc.side, nonModal, got) + } + } + } +} + +func TestDrawerSizeLimits(t *testing.T) { + a, _ := newDrawerApp(DrawerOptions{Size: 5000}) + if a.panel.W != 720 { + t.Errorf("oversize width %v, want 720 (90%%)", a.panel.W) + } + a, _ = newDrawerApp(DrawerOptions{Size: 40}) + if a.panel.W != 160 { + t.Errorf("undersize width %v, want 160", a.panel.W) + } +} + +func TestDrawerModalTrapsAndRestores(t *testing.T) { + a, tt := newDrawerApp(DrawerOptions{}) + _ = tt.Click("Behind") + if a.clicked != 0 { + t.Fatal("modal drawer let a click through") + } + a.open = true + tt.Frame() + if !tt.Focused("Close") { + t.Fatal("focus not in the drawer") + } + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyTab) + if !tt.Focused("Close") { + t.Fatal("tab left the modal drawer") + } + tt.Key(0, ui.KeyEscape) + if a.open || !tt.Focused("Filters") { + t.Fatalf("Escape: open %v, opener focused %v", a.open, tt.Focused("Filters")) + } +} + +func TestDrawerNonModalLeavesWindowUsable(t *testing.T) { + a, tt := newDrawerApp(DrawerOptions{NonModal: true}) + if err := tt.Click("Behind"); err != nil { + t.Fatal(err) + } + if a.clicked != 1 || !a.open { + t.Fatalf("clicked %d open %v", a.clicked, a.open) + } + if err := tt.Click("Close"); err != nil { + t.Fatal(err) + } + if a.open { + t.Fatal("close button did not close") + } + a.open = true + tt.Frame() + tt.Key(0, ui.KeyEscape) + if a.open { + t.Fatal("Escape did not close the non-modal drawer") + } +} + +func TestDrawerSnapshot(t *testing.T) { + snapshot(t, "drawer", 640, 360, func(c *ui.Context) { + open := true + ui.Column(c).Padding(24).Children(func() { ui.Text(c, "The gallery behind") }) + Drawer(c, &open, DrawerOptions{Title: "Seating chart", Size: 300, Actions: func() { + Button(c, "Reset", ButtonOptions{Variant: Secondary}) + Button(c, "Apply", ButtonOptions{}) + }}, func() { + ui.Text(c, "Guests are placed by rank, then by arrival.").TextColor(Tokens(c).TextMuted) + }) + }) +} diff --git a/dropdown_menu.go b/dropdown_menu.go new file mode 100644 index 0000000..aafd4cd --- /dev/null +++ b/dropdown_menu.go @@ -0,0 +1,44 @@ +package mujica + +import ( + "log/slog" + + "github.com/egoist/mygo/ui" +) + +// DropdownMenuOptions configure a DropdownMenu. +type DropdownMenuOptions struct { + // Icon goes before the label. + Icon *ui.SVG + Disabled bool + // Label names an icon-only trigger for assistive technology. + Label string +} + +// DropdownMenu is a button opening an in-window menu that build fills. +// Click, Enter, Space or Down opens it with the focus on the first item; +// the arrows, Home and End move, Escape or Tab closes, and the focus +// returns to the button. It returns the button. +func DropdownMenu(c *ui.Context, label string, opts DropdownMenuOptions, build func(m *PopupMenu)) *ui.Element { + if build == nil { + panic("mujica: DropdownMenu needs a build function") + } + if label == "" && opts.Label == "" { + panic("mujica: DropdownMenu needs a label or Label") + } + b := ui.ButtonBase(c).Role(ui.RoleMenuButton).Disabled(opts.Disabled) + if opts.Label != "" { + b.Label(opts.Label) + } + open := ui.Local(b, "mujica.dropdown", func() bool { return false }) + if opts.Disabled { + *open = false + } + if b.Clicked() || b.Shortcut(0, ui.KeyDown) { + *open = true + slog.Debug("mujica: dropdown_menu open") + } + popupMenuTrigger(c, b, label, opts.Icon, *open) + popupMenuOpen(c, b, open, build) + return b +} diff --git a/dropdown_menu_test.go b/dropdown_menu_test.go new file mode 100644 index 0000000..78bb9cc --- /dev/null +++ b/dropdown_menu_test.go @@ -0,0 +1,159 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +type menuApp struct { + chosen []string + pinned bool + locked bool + panelBounds ui.Rect +} + +func (a *menuApp) build(m *PopupMenu) { + m.Group("Letter", func() { + if m.Item("Rename", PopupMenuItemOptions{}) { + a.chosen = append(a.chosen, "Rename") + } + if m.Check("Pinned", &a.pinned, PopupMenuItemOptions{KeepOpen: true}) { + a.chosen = append(a.chosen, "Pinned") + } + }) + m.Group("Move", func() { + m.Submenu("Move to", PopupMenuItemOptions{}, func(m *PopupMenu) { + for _, f := range []string{"Archive", "Drafts"} { + if m.Item(f, PopupMenuItemOptions{}) { + a.chosen = append(a.chosen, f) + } + } + }) + }) + m.Separator() + if m.Item("Burn", PopupMenuItemOptions{Disabled: !a.locked}) { + a.chosen = append(a.chosen, "Burn") + } +} + +func (a *menuApp) view(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Padding(20).Gap(8).AlignItems(ui.Start).Children(func() { + DropdownMenu(c, "Actions", DropdownMenuOptions{}, a.build) + Button(c, "After", ButtonOptions{}) + }) +} + +func TestDropdownMenuChooseClosesAndRestores(t *testing.T) { + a := &menuApp{} + tt := ui.NewTester(a.view, 500, 400) + if err := tt.Click("Actions"); err != nil { + t.Fatal(err) + } + if !tt.HasText("Letter") || !tt.Focused("Rename") { + t.Fatalf("menu not open with focus on the first item: %q", tt.Texts()) + } + _ = tt.Click("Rename") + if len(a.chosen) != 1 || a.chosen[0] != "Rename" || tt.HasText("Letter") { + t.Fatalf("chosen %q, still open %v", a.chosen, tt.HasText("Letter")) + } + if !tt.Focused("Actions") { + t.Fatal("focus not back on the trigger") + } +} + +func TestDropdownMenuCheckKeepsOpenAndDisabledBlocks(t *testing.T) { + a := &menuApp{} + tt := ui.NewTester(a.view, 500, 400) + _ = tt.Click("Actions") + _ = tt.Click("Pinned") + if !a.pinned || !tt.HasText("Letter") { + t.Fatalf("pinned %v, open %v", a.pinned, tt.HasText("Letter")) + } + _ = tt.Click("Burn") + if len(a.chosen) != 1 || !tt.HasText("Letter") { + t.Fatalf("disabled item acted: %q", a.chosen) + } +} + +func TestDropdownMenuKeyboard(t *testing.T) { + a := &menuApp{} + tt := ui.NewTester(a.view, 500, 400) + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyDown) + if !tt.Focused("Rename") { + t.Fatal("Down did not open the menu on the first item") + } + tt.Key(0, ui.KeyDown) + tt.Key(0, ui.KeyDown) + if !tt.Focused("Move to") { + t.Fatal("arrows did not reach Move to") + } + tt.Key(0, ui.KeyDown) // Burn is disabled: wraps to Rename + if !tt.Focused("Rename") { + t.Fatal("arrow did not skip the disabled item") + } + tt.Key(0, ui.KeyEnd) + tt.Key(0, ui.KeyRight) + if !tt.Focused("Archive") { + t.Fatalf("Right did not enter the submenu: %q", tt.Texts()) + } + tt.Key(0, ui.KeyLeft) + if !tt.Focused("Move to") || tt.HasText("Archive") { + t.Fatal("Left did not close the submenu") + } + tt.Key(0, ui.KeyRight) + tt.Key(0, ui.KeyDown) + tt.Key(0, ui.KeyEnter) + if len(a.chosen) != 1 || a.chosen[0] != "Drafts" || tt.HasText("Letter") { + t.Fatalf("submenu choice %q, open %v", a.chosen, tt.HasText("Letter")) + } + tt.Key(0, ui.KeyEnter) + tt.Key(0, ui.KeyEscape) + if tt.HasText("Letter") || !tt.Focused("Actions") { + t.Fatal("Escape did not close and restore") + } +} + +func TestDropdownMenuSubmenuFlips(t *testing.T) { + a := &menuApp{} + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Row(c).Fill().Justify(ui.End).Padding(20).Children(func() { + DropdownMenu(c, "Actions", DropdownMenuOptions{}, a.build) + }) + }, 420, 400) + _ = tt.Click("Actions") + r, _ := tt.Find("Move to") + tt.Move(r.X+5, r.Y+5) + tt.Frame() + s, ok := tt.Find("Archive") + if !ok || s.X+s.W > 420 || s.X > r.X { + t.Fatalf("submenu %+v not flipped left of %+v", s, r) + } +} + +func TestDropdownMenuDisabled(t *testing.T) { + a := &menuApp{} + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + DropdownMenu(c, "Actions", DropdownMenuOptions{Disabled: true}, a.build) + }, 300, 300) + _ = tt.Click("Actions") + if tt.HasText("Letter") { + t.Fatal("disabled trigger opened") + } +} + +func TestDropdownMenuSnapshot(t *testing.T) { + snapshot(t, "dropdown_menu", 460, 320, func(c *ui.Context) { + a := &menuApp{pinned: true} + ui.Column(c).Padding(20).AlignItems(ui.Start).Children(func() { + b := ui.ButtonBase(c) + popupMenuTrigger(c, b, "Actions", nil, true) + open := true + popupMenuOpen(c, b, &open, a.build) + }) + }) +} diff --git a/example_overlay_test.go b/example_overlay_test.go new file mode 100644 index 0000000..acbcf5b --- /dev/null +++ b/example_overlay_test.go @@ -0,0 +1,167 @@ +package mujica_test + +import ( + "fmt" + + "github.com/egoist/mygo/ui" + + mujica "mujicaui" +) + +func ExampleDialog() { + open := true + name := "Ophelia" + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.Button(c, "Rename…", mujica.ButtonOptions{}).Clicked() { + open = true + } + mujica.Dialog(c, &open, mujica.DialogOptions{ + Title: "Rename the chamber", + Description: "The new name shows in every hall.", + Decorated: true, + Actions: func() { + if mujica.Button(c, "Cancel", mujica.ButtonOptions{Variant: mujica.Secondary}).Clicked() { + open = false + } + if mujica.Button(c, "Rename", mujica.ButtonOptions{}).Clicked() { + open = false + } + }, + }, func() { + ui.TextInput(c, &name) + }) + } + ui.Render(view, 400, 300, 1) +} + +func ExampleAlertDialog() { + open := true + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.Button(c, "Delete archive", mujica.ButtonOptions{Variant: mujica.Danger}).Clicked() { + open = true + } + r := mujica.AlertDialog(c, &open, mujica.AlertDialogOptions{ + Title: "Delete the archive?", + Description: "Twelve letters will be destroyed.", + ConfirmText: "archive", + }) + if r.Confirmed { + fmt.Println("deleted") + } + } + ui.Render(view, 400, 300, 1) +} + +func ExampleDrawer() { + open := true + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.Button(c, "Filters", mujica.ButtonOptions{}).Clicked() { + open = true + } + mujica.Drawer(c, &open, mujica.DrawerOptions{Title: "Filters", Side: mujica.DrawerRight, Size: 320}, func() { + ui.Text(c, "Guests are placed by rank.") + }) + } + ui.Render(view, 400, 300, 1) +} + +func ExamplePopover() { + open := true + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + b := mujica.Button(c, "Guests", mujica.ButtonOptions{Variant: mujica.Secondary}) + if b.Clicked() { + open = !open + } + mujica.Popover(c, b, &open, mujica.PopoverOptions{Title: "Guest list"}, func() { + ui.Text(c, "Twelve guests confirmed.") + }) + } + ui.Render(view, 400, 300, 1) +} + +func ExampleTooltip() { + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + b := mujica.Button(c, "Seal", mujica.ButtonOptions{}) + mujica.Tooltip(c, b, "Seal the letter with wax", mujica.TooltipOptions{}) + } + ui.Render(view, 400, 300, 1) +} + +func ExampleHoverCard() { + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + b := mujica.Button(c, "Lady Sakiko", mujica.ButtonOptions{Variant: mujica.Ghost}) + mujica.HoverCard(c, b, mujica.HoverCardOptions{}, func() { + ui.Text(c, "Keyboardist of the court.") + }) + } + ui.Render(view, 400, 300, 1) +} + +func ExampleDropdownMenu() { + pinned := false + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.DropdownMenu(c, "Actions", mujica.DropdownMenuOptions{}, func(m *mujica.PopupMenu) { + m.Group("Letter", func() { + if m.Item("Rename", mujica.PopupMenuItemOptions{}) { + fmt.Println("rename") + } + m.Check("Pinned", &pinned, mujica.PopupMenuItemOptions{KeepOpen: true}) + }) + m.Submenu("Move to", mujica.PopupMenuItemOptions{}, func(m *mujica.PopupMenu) { + m.Item("Archive", mujica.PopupMenuItemOptions{}) + }) + m.Separator() + m.Item("Burn", mujica.PopupMenuItemOptions{Disabled: true}) + }) + } + ui.Render(view, 400, 300, 1) +} + +func ExampleContextMenu() { + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + row := ui.Row(c).Padding(12).Children(func() { + ui.Text(c, "Letter to the Countess") + }) + mujica.ContextMenu(c, row, mujica.ContextMenuOptions{}, func(m *mujica.PopupMenu) { + if m.Item("Reply", mujica.PopupMenuItemOptions{}) { + fmt.Println("reply") + } + m.Item("Delete", mujica.PopupMenuItemOptions{}) + }) + } + ui.Render(view, 400, 300, 1) +} + +func ExamplePopconfirm() { + open := false + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + b := mujica.Button(c, "Archive", mujica.ButtonOptions{Variant: mujica.Secondary}) + if b.Clicked() { + open = true + } + if mujica.Popconfirm(c, b, &open, mujica.PopconfirmOptions{Title: "Archive this letter?"}).Confirmed { + fmt.Println("archived") + } + } + ui.Render(view, 400, 300, 1) +} + +func ExampleOverlay() { + open := true + view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.Overlay(c, &open, mujica.OverlayOptions{Place: mujica.OverlayBottomRight, Label: "Now playing"}, func() { + ui.Text(c, "Symbol I: △") + }) + } + ui.Render(view, 400, 300, 1) +} diff --git a/examples/gallery/pages_overlay.go b/examples/gallery/pages_overlay.go index c56982f..2458fd9 100644 --- a/examples/gallery/pages_overlay.go +++ b/examples/gallery/pages_overlay.go @@ -1,3 +1,465 @@ package main -var overlayPages = []page{} +import ( + "fmt" + "time" + + "github.com/egoist/mygo/ui" + + mujica "mujicaui" +) + +const overlayCategory = "Overlays" + +var overlayPages = []page{ + {ID: "081", Name: "Dialog", ZhName: "对话框", Category: overlayCategory, Demo: dialogDemo, Code: dialogCode, + Keys: "Tab / Shift+Tab 在对话框内循环;Escape 关闭(可关闭此规则);关闭后焦点回到触发按钮。"}, + {ID: "082", Name: "AlertDialog", ZhName: "警示对话框", Category: overlayCategory, Demo: alertDialogDemo, Code: alertDialogCode, + Keys: "打开时焦点在取消;Enter 只触发聚焦的按钮;Escape 等同取消;点击遮罩无效。"}, + {ID: "083", Name: "Drawer", ZhName: "抽屉", Category: overlayCategory, Demo: drawerDemo, Code: drawerCode, + Keys: "模态:焦点限制在抽屉内并在关闭后恢复;Escape 关闭。非模态:窗口仍可操作,Escape 关闭。"}, + {ID: "084", Name: "Popover", ZhName: "弹出框", Category: overlayCategory, Demo: popoverDemo, Code: popoverCode, + Keys: "Tab 从锚点进入弹层;Escape 或外部点击关闭并把焦点还给锚点。"}, + {ID: "085", Name: "Tooltip", ZhName: "文字提示", Category: overlayCategory, Demo: tooltipDemo, Code: tooltipCode, + Keys: "键盘聚焦或悬停超过延迟后显示;Escape 隐藏;移开或失焦隐藏。"}, + {ID: "086", Name: "HoverCard", ZhName: "悬停卡片", Category: overlayCategory, Demo: hoverCardDemo, Code: hoverCardCode, + Keys: "键盘聚焦锚点后显示,Tab 进入卡片;Escape 关闭。"}, + {ID: "087", Name: "DropdownMenu", ZhName: "下拉菜单", Category: overlayCategory, Demo: dropdownMenuDemo, Code: dropdownMenuCode, + Keys: "Enter / Space / ↓ 打开;↑↓ Home End 移动;→ 打开子菜单,← 关闭;Enter 选择;Escape 或 Tab 关闭。"}, + {ID: "088", Name: "ContextMenu", ZhName: "右键菜单", Category: overlayCategory, Demo: contextMenuDemo, Code: contextMenuCode, + Keys: "右键在指针处打开;焦点在区域内时按 Menu 键或 Shift+F10 在区域下方打开;其余按键同下拉菜单。"}, + {ID: "089", Name: "Popconfirm", ZhName: "气泡确认", Category: overlayCategory, Demo: popconfirmDemo, Code: popconfirmCode, + Keys: "打开后焦点在确认;Enter 确认;Escape 或外部点击取消。"}, + {ID: "090", Name: "Overlay", ZhName: "覆盖层", Category: overlayCategory, Demo: overlayDemo, Code: overlayCode, + Keys: "Escape 关闭;模态时焦点限制在覆盖层内,点击遮罩关闭。"}, +} + +// overlayControls lays out a demo's parameter row. +func overlayControls(c *ui.Context, fn func()) { + ui.Row(c).Gap(16).Wrap().AlignItems(ui.Center).Padding(0, 0, 12, 0).Children(fn) +} + +func overlayCheck(c *ui.Context, log func(string), v *bool, label string) { + if ui.Checkbox(c, v, label).Changed() { + log(fmt.Sprintf("%s = %v", label, *v)) + } +} + +const dialogCode = `open := true +name := "Ophelia" +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.Button(c, "Rename…", mujica.ButtonOptions{}).Clicked() { + open = true + } + mujica.Dialog(c, &open, mujica.DialogOptions{ + Title: "Rename the chamber", + Description: "The new name shows in every hall.", + Decorated: true, + Actions: func() { + if mujica.Button(c, "Cancel", mujica.ButtonOptions{Variant: mujica.Secondary}).Clicked() { + open = false + } + if mujica.Button(c, "Rename", mujica.ButtonOptions{}).Clicked() { + open = false + } + }, + }, func() { + ui.TextInput(c, &name) + }) +} +ui.Render(view, 400, 300, 1)` + +type dialogDemoState struct { + open, decorated, keepBackdrop, keepEscape, hideClose bool + name string +} + +func dialogDemo(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "081", func() dialogDemoState { return dialogDemoState{decorated: true, name: "Ophelia"} }) + overlayControls(c, func() { + overlayCheck(c, log, &s.decorated, "Decorated") + overlayCheck(c, log, &s.keepBackdrop, "KeepOnBackdrop") + overlayCheck(c, log, &s.keepEscape, "KeepOnEscape") + overlayCheck(c, log, &s.hideClose, "HideClose") + }) + if mujica.Button(c, "Rename…", mujica.ButtonOptions{}).Clicked() { + s.open = true + log("open") + } + was := s.open + mujica.Dialog(c, &s.open, mujica.DialogOptions{ + Title: "Rename the chamber", Description: "The new name shows in every hall.", Decorated: s.decorated, + KeepOnBackdrop: s.keepBackdrop, KeepOnEscape: s.keepEscape, HideClose: s.hideClose, + Actions: func() { + if mujica.Button(c, "Cancel", mujica.ButtonOptions{Variant: mujica.Secondary}).Clicked() { + s.open = false + } + if mujica.Button(c, "Rename", mujica.ButtonOptions{}).Clicked() { + log("renamed to " + s.name) + s.open = false + } + }, + }, func() { ui.TextInput(c, &s.name) }) + if was && !s.open { + log("closed") + } +} + +const alertDialogCode = `open := true +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.Button(c, "Delete archive", mujica.ButtonOptions{Variant: mujica.Danger}).Clicked() { + open = true + } + r := mujica.AlertDialog(c, &open, mujica.AlertDialogOptions{ + Title: "Delete the archive?", + Description: "Twelve letters will be destroyed.", + ConfirmText: "archive", + }) + if r.Confirmed { + fmt.Println("deleted") + } +} +ui.Render(view, 400, 300, 1)` + +type alertDialogDemoState struct{ open, typed bool } + +func alertDialogDemo(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "082", func() alertDialogDemoState { return alertDialogDemoState{} }) + overlayControls(c, func() { overlayCheck(c, log, &s.typed, "ConfirmText") }) + if mujica.Button(c, "Delete archive", mujica.ButtonOptions{Variant: mujica.Danger}).Clicked() { + s.open = true + log("open") + } + opts := mujica.AlertDialogOptions{Title: "Delete the archive?", Description: "Twelve letters will be destroyed. This cannot be undone."} + if s.typed { + opts.ConfirmText = "archive" + } + r := mujica.AlertDialog(c, &s.open, opts) + if r.Confirmed { + log("confirmed") + } + if r.Cancelled { + log("cancelled") + } +} + +const drawerCode = `open := true +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + if mujica.Button(c, "Filters", mujica.ButtonOptions{}).Clicked() { + open = true + } + mujica.Drawer(c, &open, mujica.DrawerOptions{Title: "Filters", Side: mujica.DrawerRight, Size: 320}, func() { + ui.Text(c, "Guests are placed by rank.") + }) +} +ui.Render(view, 400, 300, 1)` + +type drawerDemoState struct { + open, nonModal bool + side string + size float64 +} + +func drawerDemo(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "083", func() drawerDemoState { return drawerDemoState{side: "Right", size: 320} }) + sides := map[string]mujica.DrawerSide{"Right": mujica.DrawerRight, "Left": mujica.DrawerLeft, "Top": mujica.DrawerTop, "Bottom": mujica.DrawerBottom} + overlayControls(c, func() { + if ui.Select(c, &s.side, []string{"Right", "Left", "Top", "Bottom"}).Changed() { + log("side = " + s.side) + } + overlayCheck(c, log, &s.nonModal, "NonModal") + ui.Text(c, fmt.Sprintf("Size %.0f", s.size)) + if ui.StepSlider(c, &s.size, 120, 900, 20).Width(160).Changed() { + log(fmt.Sprintf("size = %.0f", s.size)) + } + }) + if mujica.Button(c, "Open drawer", mujica.ButtonOptions{}).Clicked() { + s.open = true + log("open") + } + was := s.open + mujica.Drawer(c, &s.open, mujica.DrawerOptions{Title: "Seating chart", Side: sides[s.side], Size: float32(s.size), NonModal: s.nonModal, + Actions: func() { + if mujica.Button(c, "Apply", mujica.ButtonOptions{}).Clicked() { + log("applied") + s.open = false + } + }}, func() { + ui.Text(c, "Guests are placed by rank, then by arrival.").TextColor(mujica.Tokens(c).TextMuted) + }) + if was && !s.open { + log("closed") + } +} + +const popoverCode = `open := true +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + b := mujica.Button(c, "Guests", mujica.ButtonOptions{Variant: mujica.Secondary}) + if b.Clicked() { + open = !open + } + mujica.Popover(c, b, &open, mujica.PopoverOptions{Title: "Guest list"}, func() { + ui.Text(c, "Twelve guests confirmed.") + }) +} +ui.Render(view, 400, 300, 1)` + +type popoverDemoState struct { + open, titled bool + rsvp bool +} + +func popoverDemo(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "084", func() popoverDemoState { return popoverDemoState{titled: true} }) + overlayControls(c, func() { overlayCheck(c, log, &s.titled, "Title") }) + b := mujica.Button(c, "Guests", mujica.ButtonOptions{Variant: mujica.Secondary}) + if b.Clicked() { + s.open = !s.open + log(fmt.Sprintf("open = %v", s.open)) + } + opts := mujica.PopoverOptions{Label: "Guest list"} + if s.titled { + opts.Title = "Guest list" + } + was := s.open + mujica.Popover(c, b, &s.open, opts, func() { + ui.Text(c, "Twelve guests confirmed; three await a reply.") + if ui.Checkbox(c, &s.rsvp, "Remind the others").Changed() { + log(fmt.Sprintf("remind = %v", s.rsvp)) + } + }) + if was && !s.open { + log("closed") + } +} + +const tooltipCode = `view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + b := mujica.Button(c, "Seal", mujica.ButtonOptions{}) + mujica.Tooltip(c, b, "Seal the letter with wax", mujica.TooltipOptions{}) +} +ui.Render(view, 400, 300, 1)` + +func tooltipDemo(c *ui.Context, log func(string)) { + delay := ui.Local(c.Root(), "085", func() float64 { return 500 }) + overlayControls(c, func() { + ui.Text(c, fmt.Sprintf("Delay %.0f ms", *delay)) + if ui.StepSlider(c, delay, 100, 1500, 100).Width(160).Changed() { + log(fmt.Sprintf("delay = %.0f ms", *delay)) + } + }) + opts := mujica.TooltipOptions{Delay: time.Duration(*delay) * time.Millisecond} + ui.Row(c).Gap(12).Children(func() { + b := mujica.Button(c, "Seal", mujica.ButtonOptions{}) + if b.Clicked() { + log("seal clicked") + } + mujica.Tooltip(c, b, "Seal the letter with wax", opts) + d := mujica.Button(c, "Burn", mujica.ButtonOptions{Variant: mujica.Danger}) + if d.Clicked() { + log("burn clicked") + } + mujica.Tooltip(c, d, "Burn every copy of the letter; nothing is kept", opts) + }) +} + +const hoverCardCode = `view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + b := mujica.Button(c, "Lady Sakiko", mujica.ButtonOptions{Variant: mujica.Ghost}) + mujica.HoverCard(c, b, mujica.HoverCardOptions{}, func() { + ui.Text(c, "Keyboardist of the court.") + }) +} +ui.Render(view, 400, 300, 1)` + +func hoverCardDemo(c *ui.Context, log func(string)) { + shown := ui.Local(c.Root(), "086", func() bool { return false }) + b := mujica.Button(c, "Lady Sakiko", mujica.ButtonOptions{Variant: mujica.Ghost}) + card := mujica.HoverCard(c, b, mujica.HoverCardOptions{}, func() { + ui.Text(c, "Lady Sakiko").FontWeight(600) + ui.Text(c, "Keyboardist of the court; writes the masquerade's score.").TextColor(mujica.Tokens(c).TextMuted) + if mujica.Button(c, "Follow", mujica.ButtonOptions{Variant: mujica.Outline}).Clicked() { + log("follow") + } + }) + if (card != nil) != *shown { + *shown = card != nil + log(fmt.Sprintf("card shown = %v", *shown)) + } +} + +const dropdownMenuCode = `pinned := false +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.DropdownMenu(c, "Actions", mujica.DropdownMenuOptions{}, func(m *mujica.PopupMenu) { + m.Group("Letter", func() { + if m.Item("Rename", mujica.PopupMenuItemOptions{}) { + fmt.Println("rename") + } + m.Check("Pinned", &pinned, mujica.PopupMenuItemOptions{KeepOpen: true}) + }) + m.Submenu("Move to", mujica.PopupMenuItemOptions{}, func(m *mujica.PopupMenu) { + m.Item("Archive", mujica.PopupMenuItemOptions{}) + }) + m.Separator() + m.Item("Burn", mujica.PopupMenuItemOptions{Disabled: true}) + }) +} +ui.Render(view, 400, 300, 1)` + +type menuDemoState struct{ pinned, sealed, locked, disabled bool } + +// overlayMenu fills the shared demo menu, logging every choice. +func overlayMenu(s *menuDemoState, log func(string)) func(m *mujica.PopupMenu) { + return func(m *mujica.PopupMenu) { + m.Group("Letter", func() { + if m.Item("Rename", mujica.PopupMenuItemOptions{}) { + log("rename") + } + if m.Check("Pinned", &s.pinned, mujica.PopupMenuItemOptions{KeepOpen: true}) { + log(fmt.Sprintf("pinned = %v", s.pinned)) + } + if m.Check("Sealed", &s.sealed, mujica.PopupMenuItemOptions{}) { + log(fmt.Sprintf("sealed = %v", s.sealed)) + } + }) + m.Group("Move", func() { + m.Submenu("Move to", mujica.PopupMenuItemOptions{}, func(m *mujica.PopupMenu) { + for _, f := range []string{"Archive", "Drafts", "Vault"} { + if m.Item(f, mujica.PopupMenuItemOptions{}) { + log("move to " + f) + } + } + }) + }) + m.Separator() + if m.Item("Burn", mujica.PopupMenuItemOptions{Disabled: s.locked}) { + log("burn") + } + } +} + +func dropdownMenuDemo(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "087", func() menuDemoState { return menuDemoState{locked: true} }) + overlayControls(c, func() { + overlayCheck(c, log, &s.locked, "Burn disabled") + overlayCheck(c, log, &s.disabled, "Disabled") + }) + mujica.DropdownMenu(c, "Actions", mujica.DropdownMenuOptions{Disabled: s.disabled}, overlayMenu(s, log)) +} + +const contextMenuCode = `view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + row := ui.Row(c).Padding(12).Children(func() { + ui.Text(c, "Letter to the Countess") + }) + mujica.ContextMenu(c, row, mujica.ContextMenuOptions{}, func(m *mujica.PopupMenu) { + if m.Item("Reply", mujica.PopupMenuItemOptions{}) { + fmt.Println("reply") + } + m.Item("Delete", mujica.PopupMenuItemOptions{}) + }) +} +ui.Render(view, 400, 300, 1)` + +func contextMenuDemo(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "088", func() menuDemoState { return menuDemoState{} }) + overlayControls(c, func() { + overlayCheck(c, log, &s.locked, "Burn disabled") + overlayCheck(c, log, &s.disabled, "Disabled") + }) + k := mujica.Tokens(c) + row := ui.Column(c).Height(160).FillWidth().Padding(16).Gap(8).Background(k.Surface).Border(1, k.Border).Radius(4) + row.Children(func() { + ui.Text(c, "Right-click anywhere here, or focus the button and press Shift+F10.").TextColor(k.TextMuted) + if mujica.Button(c, "Letter to the Countess", mujica.ButtonOptions{Variant: mujica.Ghost}).Clicked() { + log("letter clicked") + } + }) + mujica.ContextMenu(c, row, mujica.ContextMenuOptions{Disabled: s.disabled}, overlayMenu(s, log)) +} + +const popconfirmCode = `open := false +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + b := mujica.Button(c, "Archive", mujica.ButtonOptions{Variant: mujica.Secondary}) + if b.Clicked() { + open = true + } + if mujica.Popconfirm(c, b, &open, mujica.PopconfirmOptions{Title: "Archive this letter?"}).Confirmed { + fmt.Println("archived") + } +} +ui.Render(view, 400, 300, 1)` + +type popconfirmDemoState struct{ open, danger bool } + +func popconfirmDemo(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "089", func() popconfirmDemoState { return popconfirmDemoState{} }) + overlayControls(c, func() { overlayCheck(c, log, &s.danger, "Danger") }) + b := mujica.Button(c, "Archive", mujica.ButtonOptions{Variant: mujica.Secondary}) + if b.Clicked() { + s.open = true + log("open") + } + r := mujica.Popconfirm(c, b, &s.open, mujica.PopconfirmOptions{Title: "Archive this letter?", Description: "It leaves the inbox.", Danger: s.danger}) + if r.Confirmed { + log("confirmed") + } + if r.Cancelled { + log("cancelled") + } +} + +const overlayCode = `open := true +view := func(c *ui.Context) { + mujica.Use(c, mujica.Settings{}) + mujica.Overlay(c, &open, mujica.OverlayOptions{Place: mujica.OverlayBottomRight, Label: "Now playing"}, func() { + ui.Text(c, "Symbol I: △") + }) +} +ui.Render(view, 400, 300, 1)` + +type overlayDemoState struct { + open, modal, dim bool + place string +} + +func overlayDemo(c *ui.Context, log func(string)) { + s := ui.Local(c.Root(), "090", func() overlayDemoState { return overlayDemoState{place: "BottomRight"} }) + names := []string{"Center", "Top", "Bottom", "Left", "Right", "TopLeft", "TopRight", "BottomLeft", "BottomRight"} + place := mujica.OverlayCenter + for i, n := range names { + if n == s.place { + place = mujica.OverlayPlace(i) + } + } + overlayControls(c, func() { + if ui.Select(c, &s.place, names).Changed() { + log("place = " + s.place) + } + overlayCheck(c, log, &s.modal, "Modal") + if s.modal { + overlayCheck(c, log, &s.dim, "Dim") + } + }) + if mujica.Button(c, "Show overlay", mujica.ButtonOptions{}).Clicked() { + s.open = true + log("open") + } + was := s.open + mujica.Overlay(c, &s.open, mujica.OverlayOptions{Place: place, Modal: s.modal, Dim: s.modal && s.dim, Label: "Now playing"}, func() { + ui.Text(c, "Now playing").FontWeight(600) + ui.Text(c, "Symbol I: △").TextColor(mujica.Tokens(c).TextMuted) + if mujica.Button(c, "Close", mujica.ButtonOptions{Variant: mujica.Secondary}).Clicked() { + s.open = false + } + }) + if was && !s.open { + log("closed") + } +} diff --git a/hover_card.go b/hover_card.go new file mode 100644 index 0000000..6c9d658 --- /dev/null +++ b/hover_card.go @@ -0,0 +1,137 @@ +package mujica + +import ( + "log/slog" + "time" + + "github.com/egoist/mygo/ui" +) + +// HoverCardOptions configure a HoverCard. +type HoverCardOptions struct { + // OpenDelay is 500 ms and CloseDelay 300 ms when zero. + OpenDelay time.Duration + CloseDelay time.Duration + // Width is 280 DIPs when zero. + Width float32 + // Label names the card for assistive technology. + Label string +} + +// hoverCardState is what a card keeps between frames while its anchor lives. +type hoverCardState struct { + open, dismissed bool + // keyMode keeps the card in the focus order while the keyboard is on it. + keyMode bool + enterAt, leaveAt time.Time + panel ui.Rect +} + +// HoverCard previews content beside anchor while the pointer rests on it or +// it has the keyboard focus. The pointer may move into the card; with the +// keyboard, Tab from the anchor enters it. It closes after CloseDelay once +// neither holds it, or at once on Escape. It returns the card, or nil. +func HoverCard(c *ui.Context, anchor *ui.Element, opts HoverCardOptions, content func()) *ui.Element { + if anchor == nil { + panic("mujica: HoverCard needs an anchor") + } + if opts.OpenDelay < 0 || opts.CloseDelay < 0 { + panic("mujica: HoverCard delays must not be negative") + } + openDelay, closeDelay := opts.OpenDelay, opts.CloseDelay + if openDelay == 0 { + openDelay = 500 * time.Millisecond + } + if closeDelay == 0 { + closeDelay = 300 * time.Millisecond + } + st := ui.Local(anchor, "mujica.hovercard", func() hoverCardState { return hoverCardState{} }) + b := anchor.Bounds() + keyboard := anchor.FocusVisible() + pointer := anchor.Hovered() + if st.open { + // The card's layer covers the anchor, so test the pointer by geometry. + x, y, in := c.Root().PointerPosition() + pointer = pointer || in && (b.Contains(x, y) || st.panel.Contains(x, y)) + } + hot := pointer || keyboard || st.keyMode + if !hot { + st.dismissed = false + } + if st.dismissed { + return nil + } + now := c.Now() + if hot { + st.leaveAt = time.Time{} + if !st.open { + if st.enterAt.IsZero() { + st.enterAt = now + } + if wait := openDelay - now.Sub(st.enterAt); wait > 0 { + c.After(wait) + return nil + } + slog.Debug("mujica: hover_card open", "keyboard", keyboard) + st.open = true + } + } else { + st.enterAt = time.Time{} + if !st.open { + return nil + } + if st.leaveAt.IsZero() { + st.leaveAt = now + } + if wait := closeDelay - now.Sub(st.leaveAt); wait > 0 { + c.After(wait) + } else { + slog.Debug("mujica: hover_card close") + st.open, st.keyMode, st.leaveAt = false, false, time.Time{} + return nil + } + } + width := opts.Width + if width == 0 { + width = 280 + } + style := func(panel *ui.Element, p float32) { + overlayStyle(c, panel, p) + panel.Width(width).Padding(Density(c).Unit() * 4).Gap(Density(c).Unit() * 2).Label(opts.Label). + MaxHeight(popoverRoom(c, b)) + ui.Scroll(c).Shrink(1).Children(content) + } + var panel *ui.Element + dismissed, keyMode := false, keyboard || st.keyMode + if keyMode { + shown := true + panel = ui.PopoverBase(c, anchor, &shown, func(panel *ui.Element) { + style(panel.Margin(6, 0, 0, 0), overlayAnchored(c, panel, b)) + }) + dismissed = !shown + } else { + ui.Overlay(c, func() { + panel = ui.Column(c).Absolute().Role(ui.RolePopup) + prev := panel.Bounds() + x, y := overlayPlace(c, b, width, prev.H, 6) + panel.Left(x).Top(y) + p := overlayEnter(c, panel) + if prev.H == 0 { + p = 0 // not measured yet + c.AnimationFrame() + } + panel.Children(func() { style(panel, p) }) + }) + dismissed = c.Shortcut(0, ui.KeyEscape) + } + if dismissed { + slog.Debug("mujica: hover_card dismiss") + st.open, st.dismissed, st.keyMode = false, true, false + if keyMode { + anchor.Focus() // at once, so the anchor stays hot and the card stays dismissed + } + return panel + } + st.panel, st.keyMode = panel.Bounds(), keyboard || keyMode && panel.FocusWithin() + return panel +} diff --git a/hover_card_test.go b/hover_card_test.go new file mode 100644 index 0000000..815ff06 --- /dev/null +++ b/hover_card_test.go @@ -0,0 +1,117 @@ +package mujica + +import ( + "testing" + "time" + + "github.com/egoist/mygo/ui" +) + +const hoverCardTestDelay = 20 * time.Millisecond + +type hoverCardApp struct { + follows, next int +} + +func (a *hoverCardApp) view(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Padding(40).Gap(80).AlignItems(ui.Start).Children(func() { + b := Button(c, "Lady Sakiko", ButtonOptions{Variant: Ghost}) + HoverCard(c, b, HoverCardOptions{OpenDelay: hoverCardTestDelay, CloseDelay: hoverCardTestDelay}, func() { + ui.Text(c, "Keyboardist of the court") + if Button(c, "Follow", ButtonOptions{}).Clicked() { + a.follows++ + } + }) + if Button(c, "Next", ButtonOptions{}).Clicked() { + a.next++ + } + }) +} + +func hoverCardWait(tt *ui.Tester) { + time.Sleep(hoverCardTestDelay + 15*time.Millisecond) + tt.Frame() +} + +func TestHoverCardPointerCanEnterCard(t *testing.T) { + a := &hoverCardApp{} + tt := ui.NewTester(a.view, 500, 400) + r, _ := tt.Find("Lady Sakiko") + tt.Move(r.X+5, r.Y+5) + if tt.HasText("Keyboardist of the court") { + t.Fatal("opened before the delay") + } + hoverCardWait(tt) + tt.Frame() + f, ok := tt.Find("Follow") + if !ok { + t.Fatalf("card did not open: %q", tt.Texts()) + } + // Moving into the card keeps it; its button works. + tt.Move(f.X+5, f.Y+5) + hoverCardWait(tt) + if err := tt.Click("Follow"); err != nil { + t.Fatal(err) + } + if a.follows != 1 { + t.Fatalf("follows %d", a.follows) + } + // Leaving both closes it after the delay, and the window stays usable. + tt.Move(490, 390) + tt.Frame() + if !tt.HasText("Follow") { + t.Fatal("closed without the close delay") + } + hoverCardWait(tt) + if tt.HasText("Follow") { + t.Fatal("card stayed open") + } +} + +func TestHoverCardKeyboardEntersAndEscapes(t *testing.T) { + a := &hoverCardApp{} + tt := ui.NewTester(a.view, 500, 400) + tt.Key(0, ui.KeyTab) + hoverCardWait(tt) + if !tt.HasText("Keyboardist of the court") { + t.Fatal("no card on keyboard focus") + } + tt.Key(0, ui.KeyTab) + if !tt.Focused("Follow") { + t.Fatal("Tab did not enter the card") + } + tt.Key(0, ui.KeyEnter) + if a.follows != 1 { + t.Fatalf("follows %d", a.follows) + } + tt.Key(0, ui.KeyEscape) + if tt.HasText("Follow") || !tt.Focused("Lady Sakiko") { + t.Fatalf("Escape: card shown %v, anchor focused %v", tt.HasText("Follow"), tt.Focused("Lady Sakiko")) + } + hoverCardWait(tt) + if tt.HasText("Follow") { + t.Fatal("dismissed card came back while focused") + } + tt.Key(0, ui.KeyTab) + if !tt.Focused("Next") || a.next != 0 { + t.Fatal("Tab after the card did not reach Next") + } +} + +func TestHoverCardSnapshot(t *testing.T) { + snapshot(t, "hover_card", 420, 240, func(c *ui.Context) { + ui.Column(c).Padding(24).AlignItems(ui.Start).Children(func() { + Button(c, "Lady Uika", ButtonOptions{Variant: Ghost}) + }) + ui.Overlay(c, func() { + p := ui.Column(c).Absolute().Left(24).Top(66) + overlayStyle(c, p, 1) + p.Width(280).Padding(16).Gap(8).AlignItems(ui.Start).Children(func() { + ui.Text(c, "Lady Uika").FontWeight(600) + ui.Text(c, "Vocalist and guitarist; keeps the ledger of the masquerade.").TextColor(Tokens(c).TextMuted) + Button(c, "Follow", ButtonOptions{Variant: Outline}) + }) + }) + }) +} diff --git a/messages_overlay.go b/messages_overlay.go new file mode 100644 index 0000000..c2d590c --- /dev/null +++ b/messages_overlay.go @@ -0,0 +1,13 @@ +package mujica + +func init() { + addMessages(map[string][2]string{ + "dialog.close": {"Close", "关闭"}, + "alert_dialog.cancel": {"Cancel", "取消"}, + "alert_dialog.confirm": {"Delete", "删除"}, + "alert_dialog.type_to_unlock": {"Type “%s” to confirm", "输入“%s”以确认"}, + "drawer.close": {"Close", "关闭"}, + "popconfirm.confirm": {"Confirm", "确定"}, + "popconfirm.cancel": {"Cancel", "取消"}, + }) +} diff --git a/overlay.go b/overlay.go new file mode 100644 index 0000000..7b4a4a0 --- /dev/null +++ b/overlay.go @@ -0,0 +1,181 @@ +package mujica + +import ( + "log/slog" + "time" + + "github.com/egoist/mygo/ui" + + "mujicaui/theme" +) + +// OverlayPlace is where an Overlay sits in the window. The zero value is OverlayCenter. +type OverlayPlace int + +const ( + OverlayCenter OverlayPlace = iota + OverlayTop + OverlayBottom + OverlayLeft + OverlayRight + OverlayTopLeft + OverlayTopRight + OverlayBottomLeft + OverlayBottomRight +) + +// OverlayOptions configure an Overlay. +type OverlayOptions struct { + Place OverlayPlace + // Inset keeps the panel from the window edges; 16 DIPs when zero. + Inset float32 + // Modal traps the focus, makes the window inert and closes on a backdrop click. + Modal bool + // Dim darkens the window behind a modal overlay. It requires Modal. + Dim bool + // Label names the layer for assistive technology. + Label string +} + +// Overlay shows content in a layer above the window while *open is true. +// Escape closes it; a modal one also closes on a backdrop click. +func Overlay(c *ui.Context, open *bool, opts OverlayOptions, content func()) *ui.Element { + if opts.Dim && !opts.Modal { + panic("mujica: Overlay Dim requires Modal") + } + if opts.Place < OverlayCenter || opts.Place > OverlayBottomRight { + panic("mujica: Overlay Place out of range") + } + if !*open { + return nil + } + k := Tokens(c) + inset := opts.Inset + if inset == 0 { + inset = 16 + } + fx, fy := overlayFractions(opts.Place) + if opts.Modal { + var backClicked bool + shown := true + panel := ui.DialogBase(c, &shown, func(back, panel *ui.Element) { + backClicked = back.Clicked() + p := overlayEnter(c, panel) + back.Padding(inset).Justify(overlayAlign(fy)).AlignItems(overlayAlign(fx)) + if opts.Dim { + back.Background(overlayScrim(k).Alpha(p)) + } + overlayStyle(c, panel, p) + panel.Label(opts.Label).Padding(Density(c).Unit() * 4) + content() + }) + if !shown { + slog.Debug("mujica: overlay close", "backdrop", backClicked) + *open = false + } + return panel + } + var panel *ui.Element + ui.Overlay(c, func() { + w, h := c.Size() + panel = ui.Column(c).Absolute().Role(ui.RoleDialog).Label(opts.Label).Padding(Density(c).Unit() * 4) + b := panel.Bounds() + panel.Left(inset + (w-2*inset-b.W)*fx).Top(inset + (h-2*inset-b.H)*fy) + p := overlayEnter(c, panel) + if b.W == 0 { + p = 0 // not measured yet + c.AnimationFrame() + } + overlayStyle(c, panel, p) + panel.Children(content) + }) + if c.Shortcut(0, ui.KeyEscape) { + slog.Debug("mujica: overlay close", "escape", true) + *open = false + } + return panel +} + +func overlayFractions(p OverlayPlace) (fx, fy float32) { + switch p { + case OverlayTop: + return 0.5, 0 + case OverlayBottom: + return 0.5, 1 + case OverlayLeft: + return 0, 0.5 + case OverlayRight: + return 1, 0.5 + case OverlayTopLeft: + return 0, 0 + case OverlayTopRight: + return 1, 0 + case OverlayBottomLeft: + return 0, 1 + case OverlayBottomRight: + return 1, 1 + } + return 0.5, 0.5 +} + +func overlayAlign(f float32) ui.Align { + switch f { + case 0: + return ui.Start + case 1: + return ui.End + } + return ui.Center +} + +// overlayEnter returns how far, 0 to 1, the popup born with e has entered. +func overlayEnter(c *ui.Context, e *ui.Element) float32 { + born := ui.Local(e, "mujica.overlay.born", func() time.Time { return c.Now() }) + d := Motion(c, theme.PopupDuration) + if d == 0 { + return 1 + } + t := float32(c.Now().Sub(*born)) / float32(d) + if t >= 1 { + return 1 + } + c.AnimationFrame() + return ui.EaseOut(t) +} + +// overlayScrim is the color dimming the window behind a modal layer. +func overlayScrim(k theme.Tokens) ui.Color { + if k.Dark { + return ui.RGBA(0, 0, 0, 0.6) + } + return k.Text.Alpha(0.42) +} + +// overlayStyle gives a popup panel the surface, edge and shadow of the theme. +func overlayStyle(c *ui.Context, panel *ui.Element, p float32) { + k := Tokens(c) + panel.Background(k.Surface).Border(theme.BorderWidth, k.Border).Radius(theme.PopupRadius). + TextColor(k.Text).Opacity(p).Shadow(0, 6, 18, 0, ui.RGBA(0, 0, 0, 0.16*p)) +} + +// overlayPlace puts a w×h box below anchor a, above when there is no room, inside the window. +func overlayPlace(c *ui.Context, a ui.Rect, w, h, gap float32) (x, y float32) { + ww, wh := c.Size() + const edge = 4 + x, y = a.X, a.Y+a.H+gap + if y+h > wh-edge && a.Y-gap-h >= edge { + y = a.Y - gap - h + } + x = max(edge, min(x, ww-edge-w)) + y = max(edge, min(y, wh-edge-h)) + return x, y +} + +// overlayAnchored is overlayEnter, held at 0 until the anchor b has been laid out. +func overlayAnchored(c *ui.Context, panel *ui.Element, b ui.Rect) float32 { + if b.W == 0 && b.H == 0 { + c.AnimationFrame() + return 0 + } + return overlayEnter(c, panel) +} diff --git a/overlay_test.go b/overlay_test.go new file mode 100644 index 0000000..c66bc7a --- /dev/null +++ b/overlay_test.go @@ -0,0 +1,201 @@ +package mujica + +import ( + "runtime" + "testing" + + "github.com/egoist/mygo/ui" +) + +type overlayApp struct { + open bool + opts OverlayOptions + behind int + panel ui.Rect +} + +func (a *overlayApp) view(c *ui.Context) { + Use(c, Settings{}) + ui.Row(c).Padding(20).Gap(8).Children(func() { + if Button(c, "Show", ButtonOptions{}).Clicked() { + a.open = true + } + if Button(c, "Behind", ButtonOptions{}).Clicked() { + a.behind++ + } + }) + if p := Overlay(c, &a.open, a.opts, func() { + ui.Text(c, "Layer") + if Button(c, "Done", ButtonOptions{}).Clicked() { + a.open = false + } + }); p != nil { + a.panel = p.Bounds() + } +} + +func newOverlayApp(opts OverlayOptions) (*overlayApp, *ui.Tester) { + a := &overlayApp{opts: opts} + tt := ui.NewTester(a.view, 600, 400) + tt.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1}) + _ = tt.Click("Show") + tt.Frame() + return a, tt +} + +func TestOverlayPlaces(t *testing.T) { + for _, modal := range []bool{false, true} { + for _, tc := range []struct { + place OverlayPlace + fx, fy float32 + }{{OverlayCenter, 0.5, 0.5}, {OverlayTopLeft, 0, 0}, {OverlayBottomRight, 1, 1}, {OverlayTop, 0.5, 0}} { + a, _ := newOverlayApp(OverlayOptions{Place: tc.place, Modal: modal}) + p := a.panel + wantX := 16 + (600-32-p.W)*tc.fx + wantY := 16 + (400-32-p.H)*tc.fy + if abs(p.X-wantX) > 1 || abs(p.Y-wantY) > 1 { + t.Errorf("modal %v place %d: panel %+v, want at (%v, %v)", modal, tc.place, p, wantX, wantY) + } + } + } +} + +func abs(v float32) float32 { + if v < 0 { + return -v + } + return v +} + +func TestOverlayModal(t *testing.T) { + a, tt := newOverlayApp(OverlayOptions{Modal: true, Dim: true}) + if !tt.Focused("Done") { + t.Fatal("modal overlay did not take the focus") + } + _ = tt.Click("Behind") + if a.behind != 0 || a.open { + t.Fatalf("backdrop: behind %d open %v", a.behind, a.open) + } + if !tt.Focused("Show") { + t.Fatal("focus not restored") + } +} + +func TestOverlayNonModal(t *testing.T) { + a, tt := newOverlayApp(OverlayOptions{Place: OverlayBottomRight}) + _ = tt.Click("Behind") + if a.behind != 1 || !a.open { + t.Fatalf("behind %d open %v", a.behind, a.open) + } + tt.Key(0, ui.KeyEscape) + if a.open { + t.Fatal("Escape did not close") + } +} + +func TestOverlayDimNeedsModal(t *testing.T) { + defer func() { + if recover() == nil { + t.Fatal("no panic") + } + }() + open := true + ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + Overlay(c, &open, OverlayOptions{Dim: true}, func() {}) + }, 200, 200) +} + +// TestOverlayLifecycle opens and closes every overlay 100 times and checks +// that nothing grows: goroutines, heap objects or the elements left behind. +func TestOverlayLifecycle(t *testing.T) { + var open bool + views := map[string]func(c *ui.Context, b *ui.Element){ + "Dialog": func(c *ui.Context, b *ui.Element) { Dialog(c, &open, DialogOptions{Title: "T"}, func() {}) }, + "Alert": func(c *ui.Context, b *ui.Element) { + AlertDialog(c, &open, AlertDialogOptions{Title: "T", ConfirmText: "x"}) + }, + "Drawer": func(c *ui.Context, b *ui.Element) { Drawer(c, &open, DrawerOptions{Title: "T"}, nil) }, + "Drawer2": func(c *ui.Context, b *ui.Element) { Drawer(c, &open, DrawerOptions{Title: "T", NonModal: true}, nil) }, + "Popover": func(c *ui.Context, b *ui.Element) { Popover(c, b, &open, PopoverOptions{}, func() {}) }, + "Confirm": func(c *ui.Context, b *ui.Element) { Popconfirm(c, b, &open, PopconfirmOptions{Title: "T"}) }, + "Overlay": func(c *ui.Context, b *ui.Element) { Overlay(c, &open, OverlayOptions{Modal: true}, func() {}) }, + "Menu": func(c *ui.Context, b *ui.Element) { + popupMenuOpen(c, b, &open, (&menuApp{}).build) + }, + "Context": nil, + } + for name, view := range views { + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + row := ui.Row(c) + var b *ui.Element + row.Children(func() { b = Button(c, "Anchor", ButtonOptions{}) }) + if view == nil { + ContextMenu(c, row, ContextMenuOptions{}, (&menuApp{}).build) + } else { + view(c, b) + } + }, 600, 400) + tt.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1}) + cycle := func() { + open = true + if view == nil { + _ = tt.Click("Anchor") + tt.Key(ui.Shift, ui.KeyF10) + if !tt.HasText("Rename") { + t.Fatalf("%s: did not open", name) + } + } + tt.Frame() + if name != "Drawer2" { + tt.Key(0, ui.KeyEscape) + if view == nil { + open = false + } + } else { + open = false + tt.Frame() + } + if open || tt.HasText("Rename") { + t.Fatalf("%s: Escape did not close", name) + } + } + for range 20 { + cycle() + } + texts := len(tt.Texts()) + before := heapObjects() + goroutines := runtime.NumGoroutine() + for range 100 { + cycle() + } + if got := len(tt.Texts()); got != texts { + t.Errorf("%s: texts %d -> %d", name, texts, got) + } + if g := runtime.NumGoroutine(); g > goroutines { + t.Errorf("%s: goroutines %d -> %d", name, goroutines, g) + } + if after := heapObjects(); after > before+2000 { + t.Errorf("%s: heap objects %d -> %d", name, before, after) + } + } +} + +func heapObjects() uint64 { + runtime.GC() + var m runtime.MemStats + runtime.ReadMemStats(&m) + return m.HeapObjects +} + +func TestOverlaySnapshot(t *testing.T) { + snapshot(t, "overlay", 480, 260, func(c *ui.Context) { + open := true + ui.Column(c).Padding(24).Children(func() { ui.Text(c, "Score of the second act") }) + Overlay(c, &open, OverlayOptions{Place: OverlayBottomRight, Label: "Now playing"}, func() { + ui.Text(c, "Now playing").FontWeight(600) + ui.Text(c, "Symbol I: △").TextColor(Tokens(c).TextMuted) + }) + }) +} diff --git a/popconfirm.go b/popconfirm.go new file mode 100644 index 0000000..5f2c9b8 --- /dev/null +++ b/popconfirm.go @@ -0,0 +1,91 @@ +package mujica + +import ( + "log/slog" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" +) + +// PopconfirmOptions configure a Popconfirm. Title is required. +type PopconfirmOptions struct { + Title string + Description string + // ConfirmLabel is "Confirm" and CancelLabel "Cancel" when empty. + ConfirmLabel string + CancelLabel string + // Danger paints the confirm button as destructive. + Danger bool +} + +// PopconfirmResult reports the choice made in this frame. +type PopconfirmResult struct { + Confirmed bool + Cancelled bool +} + +// Popconfirm asks for a light confirmation beside anchor while *open is +// true. Confirm takes the focus; Cancel, Escape and an outside click cancel. +// Use AlertDialog for high-risk actions. +func Popconfirm(c *ui.Context, anchor *ui.Element, open *bool, opts PopconfirmOptions) PopconfirmResult { + if anchor == nil { + panic("mujica: Popconfirm needs an anchor") + } + if opts.Title == "" { + panic("mujica: Popconfirm needs a Title") + } + var res PopconfirmResult + if !*open { + return res + } + k := Tokens(c) + u := Density(c).Unit() + confirm, cancel := opts.ConfirmLabel, opts.CancelLabel + if confirm == "" { + confirm = msg(c, "popconfirm.confirm") + } + if cancel == "" { + cancel = msg(c, "popconfirm.cancel") + } + variant := Primary + if opts.Danger { + variant = Danger + } + b := anchor.Bounds() + shown := true + ui.PopoverBase(c, anchor, &shown, func(panel *ui.Element) { + overlayStyle(c, panel, overlayAnchored(c, panel, b)) + panel.Margin(6, 0, 0, 0).Padding(u * 3).Gap(u * 3).MaxWidth(320).Role(ui.RoleAlertDialog). + Label(opts.Title).Description(opts.Description) + ui.Row(c).Gap(u * 2).AlignItems(ui.Start).Children(func() { + color := k.Warning + if opts.Danger { + color = k.Danger + } + ui.Icon(c, icons.Must("circle-alert")).Size(18, 18).TextColor(color).Shrink(0).Margin(1, 0, 0, 0) + ui.Column(c).Gap(u).Shrink(1).Children(func() { + ui.Text(c, opts.Title).FontWeight(600) + if opts.Description != "" { + ui.Text(c, opts.Description).TextColor(k.TextMuted) + } + }) + }) + ui.Row(c).Gap(u * 2).Justify(ui.End).Children(func() { + if Button(c, cancel, ButtonOptions{Variant: Secondary}).Clicked() { + res.Cancelled = true + } + if Button(c, confirm, ButtonOptions{Variant: variant}).AutoFocus().Clicked() { + res.Confirmed = true + } + }) + }) + if !shown { + res.Cancelled = true + } + if res.Confirmed || res.Cancelled { + slog.Debug("mujica: popconfirm close", "confirmed", res.Confirmed) + *open = false + } + return res +} diff --git a/popconfirm_test.go b/popconfirm_test.go new file mode 100644 index 0000000..32aef2a --- /dev/null +++ b/popconfirm_test.go @@ -0,0 +1,70 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +type popconfirmApp struct { + open bool + confirmed, cancelled int +} + +func (a *popconfirmApp) view(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Padding(30).AlignItems(ui.Start).Children(func() { + b := Button(c, "Archive", ButtonOptions{Variant: Secondary}) + if b.Clicked() { + a.open = true + } + r := Popconfirm(c, b, &a.open, PopconfirmOptions{Title: "Archive this letter?", Description: "It leaves the inbox."}) + if r.Confirmed { + a.confirmed++ + } + if r.Cancelled { + a.cancelled++ + } + }) +} + +func TestPopconfirmConfirmByKeyboard(t *testing.T) { + a := &popconfirmApp{} + tt := ui.NewTester(a.view, 400, 300) + tt.Key(0, ui.KeyTab) + tt.Key(0, ui.KeyEnter) + if !a.open || !tt.Focused("Confirm") { + t.Fatalf("open %v, Confirm focused %v", a.open, tt.Focused("Confirm")) + } + tt.Key(0, ui.KeyEnter) + if a.confirmed != 1 || a.cancelled != 0 || a.open { + t.Fatalf("confirmed %d cancelled %d open %v", a.confirmed, a.cancelled, a.open) + } + if !tt.Focused("Archive") { + t.Fatal("focus not restored to the anchor") + } +} + +func TestPopconfirmCancelPaths(t *testing.T) { + a := &popconfirmApp{} + tt := ui.NewTester(a.view, 400, 300) + _ = tt.Click("Archive") + _ = tt.Click("Cancel") + _ = tt.Click("Archive") + tt.Key(0, ui.KeyEscape) + _ = tt.Click("Archive") + tt.ClickAt(390, 290) + if a.cancelled != 3 || a.confirmed != 0 || a.open { + t.Fatalf("cancelled %d confirmed %d open %v", a.cancelled, a.confirmed, a.open) + } +} + +func TestPopconfirmSnapshot(t *testing.T) { + snapshot(t, "popconfirm", 420, 220, func(c *ui.Context) { + open := true + ui.Column(c).Padding(24).AlignItems(ui.Start).Children(func() { + b := Button(c, "Dismiss the guard", ButtonOptions{Variant: Secondary}) + Popconfirm(c, b, &open, PopconfirmOptions{Title: "Dismiss the guard?", Description: "The east gate stays unwatched tonight.", Danger: true}) + }) + }) +} diff --git a/popover.go b/popover.go new file mode 100644 index 0000000..aef1a18 --- /dev/null +++ b/popover.go @@ -0,0 +1,60 @@ +package mujica + +import ( + "log/slog" + + "github.com/egoist/mygo/ui" + + "mujicaui/theme" +) + +// PopoverOptions configure a Popover. +type PopoverOptions struct { + // Title shows in serif at the top and names the panel. + Title string + // Width fixes the panel width; zero fits the content, at least the anchor's width. + Width float32 + // Label names an untitled panel for assistive technology. + Label string +} + +// Popover shows content in a panel below anchor while *open is true. The +// panel flips above where there is no room, stays in the window and scrolls +// when taller than the room; an outside click or Escape closes it. +func Popover(c *ui.Context, anchor *ui.Element, open *bool, opts PopoverOptions, content func()) *ui.Element { + if anchor == nil { + panic("mujica: Popover needs an anchor") + } + if !*open { + return nil + } + u := Density(c).Unit() + b := anchor.Bounds() + label := opts.Label + if opts.Title != "" { + label = opts.Title + } + panel := ui.PopoverBase(c, anchor, open, func(panel *ui.Element) { + overlayStyle(c, panel, overlayAnchored(c, panel, b)) + panel.Margin(6, 0, 0, 0).Padding(u * 3).Gap(u * 2).MinWidth(b.W).MaxHeight(popoverRoom(c, b)).Label(label) + if opts.Width > 0 { + panel.Width(opts.Width) + } else { + panel.MaxWidth(360) + } + if opts.Title != "" { + ui.Text(c, opts.Title).Font(theme.SerifFont).FontSize(theme.BodySize + 2).FontWeight(600).Shrink(0) + } + ui.Scroll(c).Shrink(1).Children(content) + }) + if !*open { + slog.Debug("mujica: popover close") + } + return panel +} + +// popoverRoom is the tallest a panel below or above anchor b may be. +func popoverRoom(c *ui.Context, b ui.Rect) float32 { + _, h := c.Size() + return max(b.Y, h-b.Y-b.H) - 16 +} diff --git a/popover_test.go b/popover_test.go new file mode 100644 index 0000000..a5226b5 --- /dev/null +++ b/popover_test.go @@ -0,0 +1,102 @@ +package mujica + +import ( + "testing" + + "github.com/egoist/mygo/ui" +) + +type popoverApp struct { + open bool + top float32 + panel, anchor ui.Rect + behind, applied int +} + +func (a *popoverApp) view(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Padding(a.top, 0, 0, 40).Gap(8).Children(func() { + b := Button(c, "Filter", ButtonOptions{}) + if b.Clicked() { + a.open = !a.open + } + a.anchor = b.Bounds() + if Button(c, "Behind", ButtonOptions{}).Clicked() { + a.behind++ + } + if p := Popover(c, b, &a.open, PopoverOptions{Title: "Filter rows"}, func() { + if Button(c, "Apply", ButtonOptions{}).Clicked() { + a.applied++ + a.open = false + } + }); p != nil { + a.panel = p.Bounds() + } + }) +} + +func TestPopoverOpensBelowAndFlips(t *testing.T) { + a := &popoverApp{top: 20} + tt := ui.NewTester(a.view, 400, 300) + _ = tt.Click("Filter") + tt.Frame() + if !a.open || a.panel.Y < a.anchor.Y+a.anchor.H { + t.Fatalf("below: open %v panel %+v anchor %+v", a.open, a.panel, a.anchor) + } + a = &popoverApp{top: 240} + tt = ui.NewTester(a.view, 400, 300) + _ = tt.Click("Filter") + tt.Frame() + if a.panel.Y+a.panel.H > a.anchor.Y { + t.Fatalf("no flip: panel %+v anchor %+v", a.panel, a.anchor) + } +} + +func TestPopoverOutsideClickAndEscape(t *testing.T) { + a := &popoverApp{top: 20} + tt := ui.NewTester(a.view, 400, 300) + _ = tt.Click("Filter") + tt.ClickAt(390, 290) + if a.open || a.behind != 0 { + t.Fatalf("outside click: open %v behind %d", a.open, a.behind) + } + _ = tt.Click("Filter") + tt.Key(0, ui.KeyTab) // focus follows the anchor into the panel + if !tt.Focused("Apply") { + t.Fatal("Tab did not enter the popover") + } + tt.Key(0, ui.KeyEscape) + if a.open || !tt.Focused("Filter") { + t.Fatalf("Escape: open %v anchor focused %v", a.open, tt.Focused("Filter")) + } + _ = tt.Click("Filter") + _ = tt.Click("Apply") + if a.applied != 1 || a.open { + t.Fatalf("applied %d open %v", a.applied, a.open) + } +} + +func TestPopoverNeedsAnchor(t *testing.T) { + defer func() { + if recover() == nil { + t.Fatal("no panic") + } + }() + open := true + ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + Popover(c, nil, &open, PopoverOptions{}, nil) + }, 200, 200) +} + +func TestPopoverSnapshot(t *testing.T) { + snapshot(t, "popover", 420, 260, func(c *ui.Context) { + open := true + ui.Column(c).Padding(24).AlignItems(ui.Start).Children(func() { + b := Button(c, "Guests", ButtonOptions{Variant: Secondary}) + Popover(c, b, &open, PopoverOptions{Title: "Guest list", Width: 240}, func() { + ui.Text(c, "Twelve guests confirmed; three await a reply.").TextColor(Tokens(c).TextMuted) + }) + }) + }) +} diff --git a/popup_menu.go b/popup_menu.go new file mode 100644 index 0000000..0b3db9e --- /dev/null +++ b/popup_menu.go @@ -0,0 +1,245 @@ +package mujica + +import ( + "log/slog" + + "github.com/egoist/mygo/ui" + + "mujicaui/icons" + "mujicaui/internal" + "mujicaui/theme" +) + +// PopupMenuItemOptions configure one item of a PopupMenu. +type PopupMenuItemOptions struct { + Disabled bool + // KeepOpen keeps the menu open after the item is chosen. + KeepOpen bool +} + +// PopupMenu builds the items of a DropdownMenu or ContextMenu. Its methods +// add items in order and report choices in the frame they happen. +type PopupMenu struct { + c *ui.Context + root *popupMenuRoot + level *popupMenuLevel + subs []popupMenuSub + seq, rows int + autofocus bool +} + +// popupMenuRoot carries what every level of one open menu shares in a frame. +type popupMenuRoot struct{ close bool } + +// popupMenuLevel is what one menu level keeps while it shows. +type popupMenuLevel struct { + open int // seq of the open submenu, 0 for none + byKey bool // the open submenu was opened from the keyboard +} + +type popupMenuSub struct { + item *ui.Element + seq int + build func(m *PopupMenu) +} + +// Item adds an item showing label and reports whether it was chosen. +// Choosing it closes the menu unless KeepOpen is set. +func (m *PopupMenu) Item(label string, opts PopupMenuItemOptions) bool { + it := m.row(ui.ButtonBase(m.c), opts.Disabled, false) + m.content(it, label, false, false) + if !it.Clicked() { + return false + } + slog.Debug("mujica: popup_menu choose", "item", label) + m.root.close = m.root.close || !opts.KeepOpen + return true +} + +// Check adds an item toggling *checked and reports whether it changed. +func (m *PopupMenu) Check(label string, checked *bool, opts PopupMenuItemOptions) bool { + it := m.row(ui.CheckboxBase(m.c, checked), opts.Disabled, false) + m.content(it, label, *checked, false) + if !it.Changed() { + return false + } + slog.Debug("mujica: popup_menu check", "item", label, "checked", *checked) + m.root.close = m.root.close || !opts.KeepOpen + return true +} + +// Submenu adds an item opening a nested menu that build fills. Hover, +// click, Enter, Space or Right opens it; Left or Escape closes it. +func (m *PopupMenu) Submenu(label string, opts PopupMenuItemOptions, build func(m *PopupMenu)) { + if build == nil { + panic("mujica: PopupMenu Submenu needs a build function") + } + it := m.row(ui.ButtonBase(m.c), opts.Disabled, true) + seq := m.seq + m.content(it, label, false, true) + if opts.Disabled { + return + } + if it.Clicked() || it.Shortcut(0, ui.KeyRight) { + m.level.open, m.level.byKey = seq, it.FocusVisible() + slog.Debug("mujica: popup_menu submenu", "item", label) + } + m.subs = append(m.subs, popupMenuSub{it, seq, build}) +} + +// Group adds a captioned group of items, separated from what comes before. +func (m *PopupMenu) Group(label string, fn func()) { + k := Tokens(m.c) + u := Density(m.c).Unit() + if m.rows > 0 { + m.Separator() + } + if label != "" { + ui.Text(m.c, label).FontSize(theme.CaptionSize).TextColor(k.TextMuted).Padding(u, u*3, u/2, u*3+16+u*2).Shrink(0) + } + fn() +} + +// Separator adds a line between items. +func (m *PopupMenu) Separator() { + u := Density(m.c).Unit() + ui.Box(m.c).Height(theme.BorderWidth).Margin(u, u*2).Background(Tokens(m.c).Border).Shrink(0) +} + +// row styles an item element and runs the hover, focus and highlight logic. +func (m *PopupMenu) row(it *ui.Element, disabled, sub bool) *ui.Element { + c := m.c + k := Tokens(c) + d := Density(c) + m.seq++ + m.rows++ + seq := m.seq + it.Justify(ui.Start).MinHeight(max(theme.MinHitSize, d.ControlHeight()-4)).Padding(0, d.Unit()*3). + Gap(d.Unit() * 2).Radius(theme.ControlRadius).Disabled(disabled).FocusRing(false).TextColor(k.Text) + if disabled { + return it + } + if m.autofocus { + it.AutoFocus() + m.autofocus = false + } + hovered := it.Hovered() + was := ui.Local(it, "mujica.menu.hover", func() bool { return false }) + if hovered && !*was { + it.Focus() // focus follows the pointer + if sub { + m.level.open, m.level.byKey = seq, false + } else { + m.level.open = 0 + } + } + *was = hovered + if hovered || it.FocusVisible() || m.level.open == seq { + it.Background(k.Selection).DrawOver(func(p *ui.Painter, r ui.Rect) { + p.Fill(ui.Rect{X: r.X, Y: r.Y + 4, W: 2, H: r.H - 8}, k.AccentText, 1) + }) + } + return it +} + +// content lays out the check column, label and submenu chevron of an item. +func (m *PopupMenu) content(it *ui.Element, label string, checked, sub bool) { + c := m.c + k := Tokens(c) + it.Children(func() { + mark := ui.Box(c).Size(16, 16).Shrink(0) + if checked { + mark.Children(func() { ui.Icon(c, icons.Must("check")).Size(16, 16).TextColor(k.AccentText) }) + } + ui.Text(c, label).SingleLine().Grow(1) + if sub { + ui.Icon(c, icons.Must("chevron-right")).Size(14, 14).TextColor(k.TextMuted).Shrink(0) + } + }) +} + +// popupMenuOpen shows the menu build fills below anchor while *open is true. +func popupMenuOpen(c *ui.Context, anchor *ui.Element, open *bool, build func(m *PopupMenu)) *ui.Element { + if !*open { + return nil + } + b := anchor.Bounds() + root := &popupMenuRoot{} + panel := ui.PopoverBase(c, anchor, open, func(panel *ui.Element) { + overlayStyle(c, panel, overlayAnchored(c, panel, b)) + panel.Margin(4, 0, 0, 0).MinWidth(max(b.W, 200)).MaxWidth(360).MaxHeight(popoverRoom(c, b)) + items := popupMenuLevelBuild(c, panel, root, build, true) + if items.Shortcut(0, ui.KeyTab) || items.Shortcut(ui.Shift, ui.KeyTab) { + root.close = true + } + }) + if root.close { + *open = false + } + if !*open { + slog.Debug("mujica: popup_menu close") + } + return panel +} + +// popupMenuLevelBuild builds one level's items in outer, then its open submenu. +func popupMenuLevelBuild(c *ui.Context, outer *ui.Element, root *popupMenuRoot, build func(m *PopupMenu), autofocus bool) *ui.Element { + u := Density(c).Unit() + items := ui.Scroll(c).Shrink(1).Padding(u).FocusGroup(ui.Vertical) + m := &PopupMenu{c: c, root: root, autofocus: autofocus} + m.level = ui.Local(items, "mujica.menu.level", func() popupMenuLevel { return popupMenuLevel{} }) + outer.Role(ui.RolePopup) + items.Children(func() { build(m) }) + for _, s := range m.subs { + if m.level.open == s.seq { + popupMenuSubmenu(c, outer, root, m.level, s) + } + } + return items +} + +// popupMenuSubmenu builds a submenu beside its item, flipped to stay in the window. +func popupMenuSubmenu(c *ui.Context, outer *ui.Element, root *popupMenuRoot, lv *popupMenuLevel, s popupMenuSub) { + u := Density(c).Unit() + ob, ib := outer.Bounds(), s.item.Bounds() + box := ui.Column(c).Absolute().Key(s.seq).MinWidth(180).MaxWidth(360) + sb := box.Bounds() + ww, wh := c.Size() + left, top := ib.X+ib.W+u-ob.X, ib.Y-u-ob.Y + if ob.X+left+sb.W > ww-4 { + left = ib.X - u - sb.W - ob.X + } + top = min(top, wh-4-sb.H-ob.Y) + box.Left(left).Top(top).MaxHeight(wh - 8) + p := overlayEnter(c, box) + if sb.W == 0 || ob.W == 0 { + p = 0 // not measured yet + c.AnimationFrame() + } + overlayStyle(c, box, p) + box.Children(func() { popupMenuLevelBuild(c, box, root, s.build, lv.byKey) }) + if box.Shortcut(0, ui.KeyLeft) || box.Shortcut(0, ui.KeyEscape) { + lv.open = 0 + s.item.Focus() + } +} + +// popupMenuTrigger styles a menu trigger button with a trailing chevron. +func popupMenuTrigger(c *ui.Context, b *ui.Element, label string, icon *ui.SVG, open bool) { + k := Tokens(c) + d := Density(c) + b.MinHeight(d.ControlHeight()).MinWidth(theme.MinHitSize).Padding(0, d.Unit()*3, 0, d.Unit()*4). + Gap(d.Unit() * 2).Radius(theme.ControlRadius) + internal.Ring(b, k.Focus, theme.ControlRadius) + bg, fg, border := buttonColors(k, Secondary, b.Hovered() && !b.IsDisabled(), b.Pressed() || open) + b.Background(bg).TextColor(fg).Border(theme.BorderWidth, border) + b.Children(func() { + if icon != nil { + ui.Icon(c, icon).Size(16, 16) + } + if label != "" { + ui.Text(c, label).SingleLine() + } + ui.Icon(c, icons.Must("chevron-down")).Size(14, 14).TextColor(k.TextMuted) + }) +} diff --git a/testdata/snapshots/darwin/alert_dialog-dark.png b/testdata/snapshots/darwin/alert_dialog-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..48cc493ea82e28644dd67686042bfdf7d72f56a1 GIT binary patch literal 18244 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/alert_dialog-light.png b/testdata/snapshots/darwin/alert_dialog-light.png new file mode 100644 index 0000000000000000000000000000000000000000..b108d13ecf00c624c436640d57097311c87ceb87 GIT binary patch literal 19465 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/context_menu-light.png b/testdata/snapshots/darwin/context_menu-light.png new file mode 100644 index 0000000000000000000000000000000000000000..6699812fd33b3c572d741f6ed0d11ea2ae994ae8 GIT binary patch literal 13791 zcmeIZWl&oU+b-HtXwf1qUYz1qT#CCFOCdM}x8m+zibE*Hp|}SRR*DncgBCCDZaX~B zyZ4^`=luER+jGv$nOVuovaDOKb^D6^q#}!jPJ;gI*)uG8IVtsL&z=t=K4Pdyh&^qv zd8cR3cnajD#5FzA_ZHDK-+Z2bb(9vJ4MJgMprV#i+NgQiLD}(DHyOBLqc&MtU!>K1 z*mr$bQWM?;0Qi)68A)RK@VkQ%TaLdnp zANXXqmYPzVntD&y%sKHOJK~H%Vw5<2r)ap#&p^+0#0cV0{y($weggsd|kr}`jlBha?ztg=y#`oj8Kb7 zf5P%`hVK24jL)NU>Ia5T*)5u(wN7xtE4P%q&+a?azpB^Q17E)u$qVt2R2=8zYLEK* z^()-_eR}}RanHhn5EuVkQ9+?x!S%$2Bwp@ga^{1_RL026?zxbON!xNA*Tdhjldrm& zNY6u+hKFFcw%45Kp%C+lf~a=G%#VI8$4980Rm7)3r3Z`5tjuq+J_?whS-#9L@Y|gR z@6Wd_H_^POSz8Le%|yaR3Ji!vmESnwN#iS?vbL(YTit*?yrCa(axS$YU#cjXBf`z} zkSHtB@I*)6kERe+Qk)L=g*iLITih1K!k=@K3`O^@VUge2xW$Z4B#IaAp5N?yUrHS; z`BI9sRW*JW?TS{(+jfCwqny6Nc5-{i@r+6n2&g|g9qEZCmaM5xz3&LxG-vU8d?+7l zR_F338zkfY)zM+wGnYmkGKv;S%T4{!%ip$MQ?ReUzhi01vI4+wdo_&JIOfGGzj}{q_53^Q{kd=+9t1;PXvi)kte}-#HF9!u zt&madW;b$C##E7Re-$GmbCuzq2-J``nY<=_t-8mfmFMb&A6eogqtKfhfe~SaWK5t?A5wraZ@BDVt}S0U)&^{r$(u4Ey67%RmZD~K*(m8>>plFsXyIjb zG=%!^!Vcr3`KY)WOHQ`GQRlX;9uk*z_&uQM&>Z#?A%kXqAwza1FVh8n(BPU@9ne>g zTIYV_^ThouH*m3mkL+()z)HUD-jAk%`f9(@FU^bw~(}usa3+C%03&k#3Yj6RP0_@oCMH6?(kXk4e26 zC7Kz;qC-6|sWdN($Q>*bSI6-%I}srG#>0)k_e1jMul5Tbf{;om7SCPiD2E6|XO;Km z;bl$T{@`0QVc}v;>(QWVQ)z0$oJ%4K3eHree0ABz=5U8)Fsrc89L(nA3XO#Tqm$## zD6XAGzgPM`30~3S()F}D0qmM>Nbgc zN7w$7tMkVFkHm@5(a}OxijYs@V-!-<@qDvL2RHSmf5)$MG5jNRoq#*(zr=V;yG{DH zYol>-WnaJJZUqPZmY9G5i`BK3n$~*O)cQbpk(vf-D;9f?>xx{)H&qWNOMZ5?S|uS` zs1%a1{%k{NcQ;&pJLdcMY7uItfVw>w_Bwpr2_y z3tkR@(n3{&n7lmrTWKjfht%A|wlo3%%#w+k#2eweiIspn3Ib zXaS$}HX91v+Z+lDdr2=Vdsh_aZ^`kZiM3Evjv%4a>%cqt1Nl8hxyh>v?X0Y%h4@u7!NE)B%+UjaTf&y#+?1Q(uvC?5)b9=G< z#{cYZEE?Ljj?P-oH=R4bs&0Xh6A8u71V4nU=t7$>1RZCVY8HM=e-dWc*OXO6#D78u zlWN6k4BAR`)%*BU1qF0S@p7~{ECAPNgvmfK|Kf1T(Iq+>ATy^FD|>$KTUM^?z~lij zBAT9@oFsN+iCHe26fS9g%>J>v4tfdQ&hX1qnQ3q^teFbS1&BA~2>U)`jnc*3U4P57 za~`|13s<6B8pV^gV+~gEAFvhMF7LiN3>+;$E82fuH+|nn=I&(`A8G=~eBd44L!XcO z$g|$PF5omXmXozs{1_F#|G>3E^L6VUSDMhR&Q|B(*|z?6AcbpVa>&K&#h8My`)79E zqezfeGM%!CmU_*(?Z?mIDLjwHhl8eTjXV4g=E6eWQx&mSU9Jm)pC~1ml#2r-G~+2F z82T7X&~fpeBfCm6II+ilvO>92WBN(J(;ab}1q}#(i-&VW*r6B1uRx3Z0j=Zex4?SH zEF9ihb2?hK?Crc)HnVhEet-Wkw|KcUSYa~cE^?c;JlG;$D#1z`ljN20r`ThU#`_Wsypbz;HVlVRAy4+Ryo#5bA5tIc;Jp^ zw}T```oNAu)#@F&bah}ULsQXtc~4M{*-F`0U-=T>{*<2&SWETI2jZ5B1EBx{^v;Ux za*Vp5JU=B?Ngx&?+^!2MqbxW?ZFU65Uh#P>{a{aY<;Hk*k&kzo&nbgO$`<}rXNU7l z5N+3<1G?!n9ovEk({(B0^y!WFj{~fjiqF2bC8!Yfpy$(dw8l?0^Fa(ca|?4B6vVXZ zvI(Yx#-3r}av8mu26lF+H+LtO(;mG>xaDay5F`AVaXCs!ypsOR@0HD%gDJmV zYSYjm%pibtu{-!mYFt$>E%f2c3N`PO z%%^~h)?v)(UHB-IlG+bUOXHD0r*U2yi_cP{rjgp|`)>bKnRH>ms}U=SAenuA#JPh;q^Cfl0hnE*f);Co!T+)OPSLNEhpI))R1 z&uxyUfV2kRl50zv%n4*E70|RWh?%X7Yp3`&B@V2o? zi29q2s?`DGxJt+tR0-xp9qp=#MPv?#x+uSRk`*Y<6*xWSWDLgX007u1rv(gci8#F+($vpEsA)%FT z5PJU0wV$A3nQ7&Q6$H^50y)cBQTz}%2s6_{8V0)MJV#QysJicdfXQ2?p6k7KagFPz zPE2M_JZ~se)|ub`7;ff^oQv0?@PayP!y)PZFsqBYdeO*)G@!WD&f2XCEVPqbrvKfw z0$qILO=YiF^j4pl@7|695(2GG;?vAKUZ&XH^j&7YNf@8liu9U(T|2Yw(GxVcL^ALq z@oSdu=a8r}YEKN)vg`^GOtOWEa&hwscY1sB@Nu1P9WU3&Hj?&Ks@_rO?D|mA=63}q z9Hntkodc8nUn26v-Iovns*0b+OPhodGjq!=yn13a6I}jxiyrmz0KhlH`@2T+*wfIs zZzgG4wuXMZ0iPlt;`xt5-x%%+A4_9kYGkeP%Sx7TV4ChtjkRY8%rA_$xG%RgANtOx zY81xAk}2n_kBHoNt5S%ZWu(O7NEmoMgx)SUyN}#1UoJN_nTnF7W&YS{H~o_nOEx>b z^iX(we7Z$<-uQ5cLD=@;1pU#Z2nsRh7#uccAQ35S@ELZ##-vJ=rqjJu0u#J*!^cE6 zCS&fy>-FR07-yC99eF1-a2UYo)Z!x_uO;NSX|6{M?xLqbM~kA zu=Oxw+vUbvwr#4u{C@Q43oXh012auX9EjS}ZS`zl=%vW*`r4gtj&&3T16mZ?q1vhs zOlt|{$rwoXRlssv@OsJ*8WRAy{6Zg&e+A#(-rO$xEjJ%{+{g5{Khlsy^ET8X2Ln|P zcY`{NKC5C={j4disjhZ(^AgP24aOFooS45|c|oD`J*&OGQ4Y1q?)Ji$;^xo(ix-HS zmPDyn!cXQW{NHXMC1I>H60RrDxBNbfxs#|ET|3^`*f?zS>B`J<(G_yI`Frv^sAAWU z|Bi@)@-w?3T?jWX&++r39usVlKHrDuJ4mD@7|$SeVJzo%n`a(XcM{N#ym--J5;>i! z!ecYbBfY4{w30FH*-iO%`E}<_gqd5NfWeXBV>(SP9n`vmGA$qD9Wv+hRtz;Zu_mz! zCvg$aac$2dl6EVz%2MMWn=wMmM`>@`mHyt0N9V^AwtL>N``2v-#&i=@>ggK*sY8&1 zOA4$s9-(rm+q=sZy=(qg`~6CE&VEiOyCc3En)jBrBcgqN5>mcBsY zBJ*_@UOeM{QS8Tbo-S9XuS6V=UePQ+jIXKwNFCI_-1CCz9#V(2IBum0H8*E@t`-+& z`4$v5xL;;oerpx<+8EEr-lO=)f7UlPHsg0O7h4y1fzXqKmF>FW%PCFI6SbX|UILxn zFbJUi6S%_Q3{yNg?({(0dtBwi%sU6OEM^5|@&fr{D>nU9-wEN%Q&m{53sXKrU^c<} z3jl~S6%q4oWwDt5o^ln&i!?IPlc(zu=5vG;ukpS|MEh@r%IGPXmF}!oecnKMGfIP% z2vW<^Q*Bp%PE91U)W(f;k{}y9Uv^q@52VE@oq$T@^c0o!)Dn}M=ycgVLV0tHn!f6= zJ=29**j%-m_=VF%eW87->IjCiAdBmYJqHntEJU#JG7fsPW*4hu$}|->J^2^;|NA+oSn7xLf!5`rQbe`jBGztG*V0s z@6qCLDfoxrglK>$8Zz2@ZrVVAn)oM%iwcHGYUM%~P&NaDrslhCRsZ16V$y8W3}34V zin8CP54$x8>9X*TjvYgKf+VWzp_3T9C~<-1dOvYK;h@IB1cayr6tr9{CgDNLhsH7V zhn}i^6oXqIPg@*c$Du&{L7>RKk;BdiRWJloSKqlcJDcO<-J?o6|F;B!_pAzYj|D$b zAYvECeRK2ks%hpPz*U#nh75WER^5xosVSa=gUZRNDT~8J_XEA|tK-)g5<$OzOGN%v zE#6*S6qaDlIq|4YCH6Pg?)$+LFEu$clL7|o0Dw#LrI~`~$?F-q^h!hyI6lKIp~h6p z{)SGi1#UNIRzeB*&2GLAYujAv#oSERuD@jcdce{$J(=SgqLy_)heMsnG}BNCs>|)F zqtH-x79Zmko42e!`p`3WF0QuVV9C!j8OiZ#eD>V7vqa}}yOs7@w9LufQj<$dj(aCdL}vr?f$<+f3XV-helNBm-6xv{>&AF2M`(y}Fb6|3D7)e~1jkly0z}ppW*4Vw+G^~@S?R-WMmiB(A7=(o_%yrnO##8 zC4~J%JPL${7@o5nzHxf};e$=(%p|$6*TR_NDxpC0?&JM#&~+3zjGcnde$T?H|8j`0 zjoV&+zCo|aiRYIn{|956KMMiPTomb#e_-hggZ&zM(-o0uN7xlb{8?#fp$N3@$rXb< z-8EeoKAd1WU-}m;3G?o2cM`kF5l!?!Fgr01pz|b)!s`oD{*4Pw6RbF>ArgxAMzd8c z^J9*R)YZN&Z`>L!xk>7PtORR{D5@)pC|d1Fk$dz<*FGY#yN^0z;i{?^3{(%Ic32$zN}B=;)8`w6+HZCoGBPq2p8W^t zGN9lff;K@{=y5OXv^AO(58CV<@wbr6;&S7msqNvj{i=qFu8r=TMYC4PYx`&7GN7Yc z;K%ZdW7X30(_4@eKYtti6A$k^&ux3f{r&iocF zGm|UAve7X^B_+PP@N5zrQLLT!2CQys=X{crN={CxskzjLYH$BtZ}d3sT{x6&ezuQP zi!sVZ)Vd#Zn>(|M$!Fp0TnDWzF4n2Eh$yPAW)x=K-EUa__SIls(T>rntsM@vTbT;#>R8$AgHyJ?kl~{@a+GtmWrttYED!C&z&c zhxeQ0^1WX?U||!1PfclQC-K=YXmACx+0Wv{>I2TuqY;5V2uM};vyfif~ zt~_nR1~c_fy#8MS=7U5S2ZE4yru}3HD~-VWUXjc++;e=P>G?t_ef0mfLzujt#K{Wp z6Xo?63mB5St?T9n2EInH8I-J7{Q6Bu(DvjVE4R#7cKi8+gy4gz7pk$;S)$JvRC zUe!^jnU3z4Xk+fGkG(xui7tb?pHY~muAso};ZAzKp-@JKjc>61@+B%Kb!T&4$y!Xj z1rgY+Nphmvs+Yu|TJraIUa%RF`Ini+>Awe5TNUKOW0u^A4hai^^NWH7sH-lEU;KzH z$`K}WK#Adi)Ww@CACauywbYA`A|pqKaYPQ$1>PIM4N7OAu|#Rri|sQ|mKw{;&Q>U4 zWEWUS>VIK!e;)~1Jd^hS!D?Ix$hzUcAFJHmtCazc?|L6q8|rL&Q7I7}w+|`jD4IP3 zbLIAAZALDU$NNDTtvEc?zguuDO>#e2w0V=_mSpMYB4McN7=IVtN!jI z#i8i@cP+kFy~CaRhC9r5QtZ-~dkg1l?#sKR2y&hl@AAHq5-&(0eTK>|>A3gZmEm@6 zQAt~eFJyrp_VktZ>aw40=@XZAk?0?n=GxFcwDx6_YB{$Le0(#$O_f)-^frUietGg?sBCtBZQyyZ)~0(;N7|e0j#&X7q9iayl7%0j0d4_vg{>_yn6G zFG7(5WgF~j1ou=LVBUwqIbvdJNpn!>7fJ@|l|PK7ooYZJ$=}bBhWT&p9WyVeN>i3GX>Dox^ zEKpC+mNOOT>&?u>e1018zp&dx%S=7xrmGfz{C9;W)4Z~c{%fx0ylt;wyK>iBe82po zsy-lG_*Qh)rMXRT(!Sj{7;Zc5H)t<3?a7@ghrr3Q|JI_R-@(+#vwv_ofVX*ZPGUW>uz@}?^7F-> zw_VnV?T2NZW_i(oT(Ae@STU}z3ad#mMw^zP=tyhPoPz$R)P+w|N_2_7k;93v z$qM)c1SFV`r-Ld(!%Sa|A4>Hnqsu$mD#jsoFM~U>859n*J}}I+V<_BKCHVf{B(J@3 zc(hPK2$Mw^zB`)Odc#2yeRF1Q#+`ar{Pc{8H6wzT{UHB&6wH@vb1$E?`G0NMWQX|I zxL>L%FJ4moYUe{c5(>NfN~`l`c<*b-+p0RCM7BDs>ML3_OnrRri$A>E^4 z@{;KAG7v@~&~kOsbh&OqAC-FpLz_GI7;nX*{R@G-?fyGMQD7xaLUv zQBD1H%$AeW?d>gvx2;O|io%vNHCi>WTq~I;b|g&^)zkNOcsv1O0cPztXx+IwenaYt zvc{m(Zfs}tM=6xrsWYrj!uZej1jX(NpCT=G+sOdz;o-s4^IBOsYhq&wzoF*zZM;yu zZL1mgxbagMQ5H_aoC3?ur9QMZFJ-cM_nP-UoaA%t+4*^L%IEd1_OqxhXF!GCL%4es zW>^IjT4S}n!`^;ZlAoW9bFy7{E-5KVGPH`gM?wN*2nCv+PGMnTW4L$$Gwro@Smqsb z*sx{NLeCn(&b+TuX#GC2<$qL&m#(#n!p(}JqaB(wFHnw?qRJ?rz*~-QyHagmo439144OyP8on2w#5tmAVSOg`*!pcH$MBAHHQ7+HV zU9k)Di>+-`W4`gLWC$i^R?vlDV)8RrNyKxECWn*%IG^At4Gj!DQ|t{l(v0I!b5#k=y}(lK=j_Sw=<*LKja$C9xNv zM@7T-55dWuX^_julZfaC?Hn9LMxfG!SaKJKHv4@B0G5_TYzEF9IAi*a>gx5|ZqJ0v8otjuht z(oodtC$Mzrr|B>q9-661l0(bGX0OFV$xK5TY(n_x*CV?&jxs75dIHm1)t2+!hP71! zbmWH+oNDc#noI_ZH$C)OlloB5Y;83qqnaJ(`FLV99skuUSAU^f&r^Zs#fq^a>lku> zhsWCtGQ$>)+J=gQGGK-Rp_iID45Yif@Z4BfQ5ykAdReeB5g$aom{#P$Dqik;dV-6^ zg7Ee5!E#7=c#2mE zo=stIzuRRYxYkI;A149C7y_d51hg}^KNz_@^cQ8_Pn8UR?Xb{jP_Cmy==Hg0i8tIs zf#?+Lg|JLpcjF<5#QWpTZ$a<9@BA{PFu`}PXQDPrGrvf`yWiO+ZCv9QL%sNOX|!z>qf1@H4bOh7Bv&yIX6pqwb#OBgX6NKA zs=oMdO?0O*;<{gT`M8Tv7PM|-3QM&Jk{_qqA%bKta>&)#4}d7}Uvi!gp!|of1_QQd z|E(nbQ;hmQ(t07~_>C3T`-;|ljm3AbU%_I?otxf0nXo78t`TW#C7(Lx0dtk}@$vnM zCof@=F7`)t>z{)NMwVVdLU42}`|hq|YgoKb3#zNDo1jqh?ynmzcu&v$Q$lr515o7Lu<`x zf*$z*2PO=%X;8Ch@6Jlq*-2ww)BS-{0(F}wZFj_v4ljy;?c0V^(~B3uWMqbC7Z)Pe zpxRHgwnYwmHD_barvJLu*?zBkm5ZQjaZw8-1Xf%YE<4-GQklXNvs9|KxM$eGh4^&eze@&A+dNr9~G$1QKEP_ka`1BD&db zKVHa54Fo-Yh)^&Q*dJll7hrVd>8MW{WIe-!RssAaFc#p0-aKI*GfGUa+~r6 zjErtQ@cZt#jTMZK_&rSY#$qR_Z&@IQgYLGl{qH7fEZUdn<`N$8?yu;v^DS-NFCSbi zBr0d-;n!nucmS1<=gI#yux;GPLi0{*oKN0 zO%XwlvAS?p#*%M;T!)UJpOVU+K?3%$0&Kl)`QKUP*G=ny)nq7QM85;_Ra8~XP?5z| zy)_j45rW#?Z%;yJ*1N5x<~{Gs;4hn{TvYVPZX*iEY7Pb+;29tdp+Da_+OtI z3M~$IbmYZSh%n`@`g0ZU2x`V2iP&!XW=~v(tA|yn&H3?Y6}J>^SfWp0|M5zo7;)0Ynj4_e8TVTv?w+v;U@86MP_Aar)BqvQh7)tV2a! z=V9g0;fm`KG}@DlQdbDXxIZm*bhCTp6`{3llyrcEXqN!QrY{XkzHEVBVb=e6ug84S z)5U<8a<=;jVwQO2B)!nDzo){+U09}pOCdZGTt4*-9xV=5hzk9o9(Z`VNnB1p{#?9t zpfPa|rqD#GHMOSlbTJa>O>T)1n3VCf0WLB6bsU&@iHyc{lkOr`iV;`-9AY(t-*ZE; z5+S&_G9( zrv9gy8jO=yZ;v$42iw2r51N|Hwz~RJYw(dJMjkjUxAF^+$F|M4dHdT`EpDHmT6p|9 z?CZHBgBzuZc>cA%v*K=Pn*N>AkK*w{gae%L2&0fp>FbW zEHiwoHx@qA&<5Yn$`vAQk2g*qq0o0}`usrCndfd~numgaWUbVuw=bagJ?c91{f;tPU$%Sv?1*+FTjWC=;qG1Wf639JdEMMOH=>u-wvI~ zh+vnnT=|<8igK~7i%c+2Ec|0@*uJr1TijFJk_t+GQbR}d zM?ch$?~FX^p6RFNxb>2SWt2cte{k$stvH z=I_~vrl00@tl~D-1Go}uOI#c|6!C_=id?vmN5jhLWX0x=09&MO$dwQ&y@QU=@`<7^ zN^~~RoJ#DoDZ%Fs0dSw^Ti9KC;9rng!63b~KQzoYsFclWeRQcdqt=x2KU8@Y2XvlE zs}ZEUf{p2Q=JEoILPJ*$BE^R^i3crXj-4QmRwx$v@+zFHmCv-T`Hk2 zx}|OIB6gCKbTMP{Y%7cvh)EXPL@H9LO1$@$`w2Az_QXcBPShPuP*Mx{fOmb83QG&T zVC|*0vW%iAd2G|p>x;KyNh8lKT8*aaX?LD5J$ISOXg85R8rz0 z$@vly%bMKxUgl2qc*Vx7i!Tu;+XdSSSP1CB@o>gD62A=Mjdb`e?z@-4Ik+QfqJ z_`N{8VZ1oqKUgY1{BJP=7M~eChlh#Re~*r)m2(wIHLYBQA7_UJimEl64r($wXc^4lVtsmr#E=){i{=0$jA3IOsx;da z+kL|-Yl)BzW)uK^qC~G~T$o4!QTc z^Ur(h&8&aknpywMtXXHT)90Kmr*>8ClC!HiLRDE7{WbAxI5;?Tc{wR{I5>C?IJg(_ z$neik#H@!E;oxK~GY=8QBBOFCBIlx zI$F;wJVtzzLI@al>J zdjMzt#0t%?ZDxIWDNwJ9-zIlliN0XTYHY_NMIq+0jlp;{nI&nqlk-3|W6r`*7x}TS z1<0g@Oy$+0g&W$pFuHxc$-O*c)wu1OWBQq8qPq45k00S*H1{x$N2W@5cpR93F{Re) zvnI&71UmAjD?n-jVoR&$50^(zq;}DZ*v5QvGB4lLVV6?LQP5mb2-AWRHX&7T|KgaP zf)A5+^=CJ0s`Oy#tPHmu4}Ez%JD%N?qHhzn=6ZZd!;a2JJO&k=Xj~!(M!=RX*JiWQ z`|YuH{Wi``FIINe<=|sS@KU=!Y{Em({0&0w9IgCt$*3_}Zk%hDljXZzmstzF*q+$! z$0{!F10(%NEI_5P-s^DK)9DP70t!-hxsj1;OLh$lgT@X8xfqc?cGi{3ov=&+74Yrh zVY^bU)ecv|J@_E?$yu$>w&QV22p}hb`z8D0gjB~_u6lNLIVgIWH*(lY4|&v}!mMTL z-LOUQy=%$B9-|8eexs0sRBCW6S<}*p=I;62h>8b!B(dt`hkQg_-ml+Q*QC*z@W4~b zglM;OL{$@(>?zENlNN+EO|HX7S9p;{O7yTZzlMfNZZvKdJLI9^E!5C}Jex*?swyBA zNJ+^C4biwryPCzGXB+micFCAMU3k@JX;&c`tBYf3D~30BCVP}%d`C$DR~4*vE=yRX zUSY-k4j{*urt;fcn6xA_%Yzo1;kh3NKR3lO4q)qk0?e!yW{DZM7Bc7I?!M%}H*VR_ z?%cQc?vt^YkJYxZapbw*!))gp2-kDN@Ff`n)r>KlYYY2stNQ1WF8o9|_-m_OwQk^a zz3lC~_dH>4H%aHV0=QTR+G9tN6oytPIS@AkTzM&E=hoWcf3buJz-VU}~HkDXOJusPR9GEHTM zH=NA)v86G9wgr}cedXdHSHWl=a1}mjz&cU_PqFEgf#Sm^%lT=CK{6HEL@{C7;CfH@ zK$j@>97<#>K}p+ulb|E7BDWq3u1XeZUlIQDeUmxva6UDj#)WK+TaM@Pd_|npaIZT} zZIrC2(-STK5#SVP>J`fZ0;DO;bV&@kOAnKK>1CRDFEi9N5;I;SqL*s2OxdAlD<_ol z`^0hm*q*Q)u~>xe#j)w820nB=1U+S0A{aHNaoK-ofz+T$3T7)8P@&&pV#YB~aZd%p z=A1aOBiX_-hPC<9(r5>$Uwc^K;z2HVUUy4}F?$Od0Y1x!+)_^3T^Ptp{R0sJ($2;9 zg)o&Ay<7FSdtX()wBScG;JY=Odi*F=rZgi#q_!(F#*~z@cWDy|!%WunX^<0C;F@!X zv7g9+SIKg`;L>41umfg#y2ra-f$U(R(MgMzrJMEK_I*fAw^MfZ$ykC~WKqq8Ex}On ziQQmRnJ)FGdVB)OIm7muJ$821aiV`zoG2V^(ij#70%6!2=~~E6Jc@jFR_b7iLJ__Z z8hC2g&*(McgG|BdC~&zTi7iXL)UaZTpz92++e0v0)h0GJOTJ#4qMds8YIEJ^l*}9L zu_rER)n#RC>q2w)*QT3~$f31R%OUF5Pqw0KnBLOPn12EvRrG3$wa4TQy6gh@eb=&E5s=1re#fR*<_ zncCu4?EcPogeZyF*a`T&g9xFTy9fjlOwKqtv+%20FCr@5R7Z>~| zJ)v=B*AYlNL)-l>2cX&7n{EbKA)%e>lQHHr*m$s2+X5I?zuXe&d3Cr|rTjCU5Hnmh zJbApsxul^X(bGMwB+$^a;rGIiM&GBd(BDYhW$A{Rr_>r%EL& z{_CFH>EM&#As&AJ9azk8Z!YH;)jvm@UHBx|at3_k(f%b`VA*zVL#SdjK#N8!wGDo$k*^VNhX0%$w{KeET+ za?IX=`UOfn++XDpK@RO1l<)IyI^yuO{|A;`_;|oWo@#La{u_WCd$ABx-o6mjxecgte5|!v`y2M2ub*I<&t9S9(C1jhe%(vtQc3k_I&7>&p>|uwY6Px?dor z1jVzB+NQWLxa%^d8P4#Ar`OnzCNH_}_}Efm-%;Vk&?!FxDM6omu?HqQPsi)T(iD)X zmaY9tpMActApfVOLwz~ld6QaQfW@`^o73$5JD1n(u7(9aZ4 zGKnX(vsc~s@+LgnA2V{dc^xk3upJsj`&IbWoA1Al6GOaE)P5#VQ}GZ-Q}-3Lspj3_ZdG+?Q5jXLOp)P{BH6a1gXIf{fDPsJLQem(ug0m ze(Ie*EI+IZvt3mRjXdlhEoKXKOAy!eV-iVVSI)XcMtPe;L? z-urGGej!*sW7_5f*z-*F9g_+Ly+*;qW}?-U`xdWCm99tiZ{AK7Iqjd87<-<&Ro#Bs zM0=k2K0E*K4jTVOhkq2wf6Y($_j^&}KPXo@(S4L&l23f-<5}TEw-PDt9B0e<17jWl z@DI?nO#dsnW;>x0W`r`-ZxoBL1v%S1o)?d=uK5}GSh?>}s>y^OAwXJOdFU4aV9L(Azqd2k9sf#)9U(=z zf&&nR{v}#`hGP*|n>^SEH3mSq1UWAThM5Yxg1^5reC1q>+_f_+|FSF*bNMqNCB32KRODRn$xOQR*~^PiwV;SD2|3HPwL# z&U#bwYtdZ(o!qIjM++Y*>O67EuWe)9O0XK55M3)DtNke9%vFNYh6b;B+MFEn+}^%x zA9hV9ytw8%e&u8X~V%V&#>Eoq>zFG@vFa5g-YRfB1Rj4T@oH5UId z?|k6J=lXiB#jyI$&X1Q~wM1b=goO8ZDfa%CThJfA{=Xy?R5S&I-mzh#Co0f2I?ccc zNGA*{H5hu>pPxW19UTwmTHGKiIx%<4+pVs5EUrtK53ROwg+)PmQ@cDF&62W_+k~cs zR_{GFWI4fETY~2o7f&~fJ<&%s7fT{IVo{7E%CRUY6n8g%BkAV$9B5NB{2Syf!tR&C z+5Aoz7+yjRvWR8(J!Wd|?vU7_K$!ibSr#QN?R5q3SVFs~bB%U=LqoQ(rxoWEJniy8}g&1@#@6;g9kGZxpROJiws^QB4W z7{cLMc?F#tj@8-BWSslRlIL)UDmxB z>3b$?}r1`mPgxCi)!c;pH`8fqjYE5;JTMbkxqRX#Nd_ie37H+rH&J zapfP3+tv%t)96=J78GcdOia93-#YkGc&`Qsj{9oDQ(8$Tcac7zt5 z-n3p`hRg3()pB)sdV9}3X0ldPII?0sDqc|=wBOb=HpV?5uB@0`4NoV3PvJ!TWO`Bd zxdO<510X)+E3&o-Ol$YObjVZ@yXoiPsbh!zh6HFA)6$pk1NpWOF@d%cw83g!Oj@1<;S_|_tYz+ksUbWft zcKnWgWg0EI+0%j(soE8Ijn?IY8hFKAs+|a-ufJ7j)``Qbl~JRBK;l2r8Je1AJ|~OA zT&Cx#X6artpSP8zdDB#GL$5Wz{k-j zqa*An9{B>1k(e77jD_aFtNCCD6Mc(^Fh^&0gZe#S`VdBVx>8JSj*so42)A-t>brT6 zQiedKV!?0bo2|7QkE{cTr-5=>PEl0r&N@dMX@fOz`iH+&Yr74?oe8T(BqOtIU=Cu!tXPFcw)kmPT|UYBXedy}bRcXdPSBX=C{H!Hbz zb~84{#77sO?JifQdPx|hnvd7-}pPN3tX+@CT z;gH4q);oZ2oA#mC%_$zBzxbRiPKikJq&**`NyU7&U5>!ba}ZmZg&i{^6fp@NetTZ!y=ZJmdu z$CvD*!SiZ3U7O`Tu$Xr$?E!~|2-z5>es3xo%ElZRt?kZOh8|8Ynjf1KlLm0HINmy) zKcTz|m`2DO4YE2TR>PedH*+5aKclvGZt`uRVdE*xVU4Nf7W%&_WD%qpz6{%g!sA5#>Pf=fgrN zrc_t&Gq*o~j{xNc)ZL%xu}>S9f^ROcCqgY?q=K%eJQKSiVVF^m_Y;^lm=2p|D%{-e z?W0~x+6xYR#X4!57mM2^34Z3uKz3s*KKUB@Sl05R30afc2YR)|gYGM+f|AE8+WO|* zcPeZ?euqQh6dBXQp>{KfXvfysP0fM@J>$QqhjpRxm(qe0Z$c=KLP^!F-Q^sjV8H#bP} zo3&^c^ck%t&V(1fDZ0CNd}Z#g44a=9t7|OC5^%-SNurM~cz9Q>o80bt;LnWjDjY+P zbv(7Jc5WjrU4n*4W6-uV|1RfYTEBY2Yq91XSUEpGj6+CH?SwHhUpH8eOl<9Pp&%<$ zik{?$KkW8~eZ=xsaA+OrW2Z@7r{w8A)xb;30vUAkGuY~C9;UL&@UT$x_V87M^Fwqc zUuCFC4ak1;2BvP!f@_ z0LEYV4e*H6)JmCISRx|Sn%)+n5qbG18w0zION$;8lZAN0F(~%#-y($e_#(x{k|nLY z#U~UL2wb1f9nI1J%c8|A%mml7()FYiQh^E!ZAOw)S~ON;t5FaTdYYMZZXHhxUEO@e zg*9gRe7?KQPonh2;xTtiw(2tTq01oq?pGu6J3m@&(OlIwRR$8xf#NZBf}1TTpf>@c z;oUcvUo7;HH8R&jQ%`c1dFcIBFFE!O0!~A(OhSbIq9)3|%P~_&7eMaRafQbl2y?=9aevtW< zoH60Nga5)wQ2P119Yb^n4Gj$p3JsdMQEL~AA6<7d&!_Pf&e3F2la}G(`I5?Fw7JI| zKz(v&1vB=%?{5#hJH82s06xWJdP&JjzkU_)@q?I` zQi!t7!(&TSn=UvijqRClFv-}CFAmbmBZAFFx+Nq&;#xwRn9b)-r-oTsJ@nu5AAMuu z0??E6ub)uUbcds%RDJv1cH0ZgEZ4qb*Jn#x;&)uDTuP6znt7?jp&MtA30XjuvhJ zfi_EqT&2KZ!VZ0F3P@(!M%}Du&%s@_j@!k!v5E`m$Dk4d?PJyKrN?Irfds$40eB(L zQCWn?8^wk0n|#NJmU+|Gx&Jc$c`Ouh_;|QN5)9g}$Zz2zo8zee^potbY@rf*#;WT7 zG;}WAi{DcC!{DbTQw~qElceO}S6Q)^e~ELvqL#qIg6fY&=3{7&&CiD)c>1+ea(g?K zwC#D-+fVNvWV9UC?~Ux57mp~}`-3M0^(&^;fx1{-lHyn!cmQnd#N&8bN~(9T#S~Iy zg*S=f3%m_MPfPWFBg?R?hXdza&mh>{C8s#()f;RnIV>uPf7iu%HgZJYrc@Yv`;!=u zfYD=m@*KMny@V5lKp9iHwSER`v62XLu%?99&^8Rs0~>?$FDF3X}*!S>SWN-gdS| zD-Ht1w~xM6`dknPFM@Ro6???%<~UAke1xZb@!U;}l@fi4guIzQ8te3GoeDImpRK>3 z$SZ#T_1e6k~I45)4EyyYrb+kx?W7QC9vZUBfks8!0Y5o0)m^9A2|46 zsVu2PDaXKxl3bum!&j}QIcBajX;8T5l}&rIUqPEjlldNvS;DbcTw4s*;Gi5k%dF3R zfyR;uF%X!m6Lis~qcivn{WdC1x@Jww_phyGRz0U^?H$2!GIy&36UkckXYSgYR!9hl zXlNKq-&B*AG=H$9*Uixl~ZtS?DxN_dS(<2P4uk*|jxbSXS5(R5{glk~a|2ml0 z#v-bobs(>D{1JEvfxMES1ckuAeA>*-iH*QU!$3E>zn!n>wF1S*jpi?f8YHIDx&;I_ zH%|crJd1RoFxM{^@4YV%nQ-aoO$ZBGWbX!cMoV3r>H;CXaH3C39RVA?C=-x}30kGk z{%%lqf$j}B<-_2R|pAhRW2t)EG->l-L^)TysWzRMkGJTjbkWm88H>^JS| z3BpLhMS6Ao1UtCe!B|@2KB*pSL2ZLebQY!BNo zlsx?wV}EKeFQmU9m;^$J6KjCnAY%xeo_Ai)Zj+=;nVWBA$2l3-x*hcbC zUjb_7Ufd*Df*eLX%&VE@6w)$6We7~{dhCS;A?mYBT&>L zKG?djcdOlqMFeSEuw`atwdxs>{JaXbdm;}O69fI8K)S3ntTrrFXSO4GX7G-HElMa9 zy3TQR$fBfTolkM@O@fvLf2??Ruwd$wqS4i`JbLkb1kJ|6yF5_xuR;)DY^Sa>%4 ze2dhJM)Y#jbiXHvl2X%tj;92KAP*2x`LbBECmXXd%Oba3FH-Hk=@6#LK03O(J%Wz! zpc95Y?4gE}K@c~!&WSW?77m^sF7K?)d_waNy{qo^=~Ha{E=aUtwtg3V%MaYK>->10 zRUP+WB|UvDM-hNc1otv_6lfg>M=?nn#%^SsNa$RxpTfi&IN*X@S26WJ9yX%TJru1Tim|@5`9Si+L>^hNcY4PL7L-OHeqfmF>pH{VP&v0_q5>fqH zy|#i_V!NtKPLP$-h7MRT?e6}yG|&(QJ-1qAzy;V{39C^!>t;LM&uX3)4jXPjh|<#w zO!_4G4cx*&XNwYM>N=+ON@9QZ^m73|ReJ|e)dVi8C*KXowu3HH>q|;CDaIkdC5Zp? z%9<-Zr2lh5!dSOTvH+%pfW$8;6tK8yV{nGPR}N5vz&rfWO1dy55lC4m+f zTdiB(RG#1BmMmH@z{BywbE26i;zvM3#?%PyYj!okR1w zgRHkubNTeZtW76>%G6=_+~RmckmoYV(@Eym^krCa>N9qmpXMMB%3ms*isjXGax+;8 z7*JA}JZs*bKp-t?& zvYk#`MnU1BkC)qTWRJ2H%%9*=8lMfczm)6Ei=7}_KhIJ|`RA3GCwhR6in4X`gD(?? zusa~1**Pg@#n+|Vn)ezfS=sL#-nTsFKn^If+*wE^SS0W%R& z*iA!Ib$@t8E8i=HGF?8DXMpdNqS)Rp+9~mI#%YnI&5wqM_8J=e0Pre~h97?zw|QRa z8+0g>FempRD)yuW>EVMhkDtfC{E1zYrS zmMz_5$6ToKVIgYNy1x)P?^2mAc0Huu#V+rUM3At!{`r+A@vF+k*SuBJ_Kv6BR=jk` zc#dxXyU{~ixm(KY+fImVoUpq~t}d<8dwKm|R(p5R9_vaMMDH_C7P>=!f*D+>nDYZJ(10b>>?{n zb`_PQCPR8Tt0C$9mNv5|c}r!B`#kc48c3Hz*H#uXdTF_L(qYt{;W=osBjDwe{cl?b{E+Y=b}-9#u7hYST$9*HPp4sD;PXwI} z0u7t7$%sy7M;vM8wcpxx13odnEH(fL^0zP1k-C|ufa|gUS+Ua(DK0!$#q;)USr?rYL3JT7d%*lt;XYBd2dyi(FoG`Ohf zRZ8b!rZECfFl*W2N4?t=PyFIa9o1uDLg)#Hd|vzJ6J&LK0kf{yd?o5CN9=z0ogZe~ zmHz7a5|RQb5Ew#RJ}uweWxz>@CPqFZEV}Af_^28RIq8WA{jw3Gl{~kOgFiF=`L4^V zmNS|YXdVz4h!w%2y*Cs_5uDMQl_p8o0~x1fZ+oP_7>m5pulqb~R@2Kszx`TnPGWEb zoV*m>x8h%gC+c@i=7+h|@d5qKxQZx1Up)Q0?)LCa1ns~W=b3j|5M_)C%Wqoe@{FoE zRK*{9EYrc0JieqR$&_mmZ7t^cuYg9Znd~v&Hk;))QdB<3h|>_nP+DGb6z_{u#y#uo ziUXsW_R{k5Ch3`v;*?dd#Qzx1L2{Ht(GQaymk1xl&+rhJAKtW~!vCp$4!!+bV*F7` ze`M(Y7Pq(ZFHs)Fb75k?)7bC_HKYT?*uq|Pe1!gVUb(uzj=}kL+^-vGuVZdcV1)EM zBUW6wQ_Zm%JWt}bh)THUX*>6raF|hdPs6O>;)UT+jBi9bPR|~Gh|_$1^BdWw4vv@# zB$ueU7yTm0uo?atDYxX}AxdNxyObJ8>CHD*yDOYEANr85`)lLGDY3Tm#-D1vOVrfb zJV}4%&Rs+Jy46$@q%U9Kxl33^)T{qimi;9+xu5JCnG`1FWNXKm5$WJ0J51L}hj~a@ z{1pWr|C{c(_z-0j^0u0l3BHNd;lU6ZCUrR1nBQtZM+g5Iiy?HVDc2p=B#QYzCpP-* zMFeE?`qqz*MURl^4K?ok@586$B9!Vqb!^)`nyv7#k$0{R9pNp^WSvgX*#nZ6K=VfD z{mX~V!^;P?ldCI;!c$CkcK<9jTDNgakUgxDCDn2#*_6vYtRuJTs{KLMrVojW1KK_8 zd3(-izAwu!>|FfmpCE=Ia$0`=wEZEn)PnZGenD-ulm3B$lRL<|89}cHvsSuZ-%j~x z`l5SURHUK-uweq@pHK@cjKnvEJyH0dK@B8)Mazs#&qT9~Nzs}rQL$iA{45f%feHWO z$#5j^jt(!0A)?1@bZcuGJmX|E)H3!YNfCFqH*DVxczF@sUbw;DvEUzXN(ks5r>o}V zRKqdK&Y7Cr+}P3*4v>1{l?)9@f0|7$daNj z$zX<#VlSsF*+q;!9Y17?J}^3Cz^3zshbu+Dg7IxDWc?%{K=>8>$0!JB6S4-PUbqht zqE2vG51Ud;pbGN^MSFh7L`l~QIFfKyfv){PfJQxGP+6$$-vf*9lSg4oEG(CoZYm2c zQ;>-m;{{dfgo@hQg3WJL@rVVBl>QVX9RW6csriKo?G8 zx(L;~cX3r|eB;`|h2t;~R&^XKiog*RpXNv=W|&^CSvInCFkLrAF%jjpw4`7jm7Jo*l){vx#LMd`YNjH| zPL-YgT2B&(s<2?)(_n#_gv6ei84`hGBq+4GW4nN4oN$ciKZe>tkfKkMFgcn@l5?Ge z*8m_95=zi6Dfu^ELZg+h;1PKHvkUNhrlctFm(Kosxq zo5f!dxdZp&WjC@$Qa-<%lYdPv&C$pI63sb*K6vS*)ok`CCdkSC*~B2u9i7?n0OSpC z$ctW#Bi_zP7Hsc2IR_VMgS`u_xX`*+T|z#=Bf1c)Q+3v|u)MNQY)DSgIrVAnx;GqO z;J3i|XQ8{l*x7G_yjksZjlvfYh-PH3a`WQ^n7NNh)Y-Y02yDz;T3&gB{R7#KKxY0@N#wcjj481scCGDNTU zVjW-Kc6{wWj)=b?@z&Rmecm5^$*v0b&n$uQ+cdF{(6&GmAEG!*U`LRo0R=|)cef_9 z>*_1Tf}K2y7ypXDPJbsS6CW0%U^y%PZFdZ6gA_uEe98v5^MsVB4Hinulr<0tg6~sV zxke!s`?${Fa{ue;`WglIbtoX_>pzqFw_vY-#NNNNMg}8s`NssGBNcK;fS~|sY>uf7 zD&>np6*&2^A`jPJCjbFs( zYi_Go;SVxc7B1&#G)L;%iWYS*{~BheRO%8JSp2jG0X<_bSKV+?*yZf!@Js%VmlZ_94BZU%cneee`#fU*^d{pe0*EO>B8hi&`mw@9&3vY zS4Eek)i@dtxI@mSaZfE+Rk6&3CO&Nup!RHdir-5fd`4+bswflI9T zNu6J-I(D_0QhJKaczDSa-$Sgy(WB$|-)HqF{XVH~aAzw^PvGke0tsL=JqS0^p}zoT zRMqizjq%UjOWFm5GIP@~&$%M=1q3Uho|#9dsEj7nMg@HRD$V4d^6ScCUPQ%&p2wj^ zFbh@g|ERg+*YSFODMn)g7GR=I>9BRmED=*X7r)-P-LkCvz~BhqlCoFgD$MeKu0!L`7*jfZ&rm;WmSonKMAm#j>yq?OQP|AVKkX z2}Vp!D&M{SAHwL$J#_=z1f5@#kz+@mc10B=B|$yB1VdCrgt_h=_%h>ql1_m;e$-XL z@lnOZnZucl&U;P%cd^zO0jKxiQ$>7i)QG=mJY_?*B=qBXr(T4Jl$Zh&m1;b_X~^Mn z!=UeIp@jiorJ+GT7ejRS%0DBzcZXskufTj@a?;5AFkr1ZTvX&?j;zJ2&S)V+DNs!K z)QvB*>TCh{6gncMlHlINh7qB02_;qal-oM)7 zs--Sva0oWWE(^uYu&U#O-d;bDEwh$Y=f#h_e~yw0Elu~+m=Nj1*vv28^AoIyeUB<; zK_8cUF7l(Kt!i&vo$=%`{g;19C>Huw@lP861JN{z3P|5bXy39P8_UDRx{* zvrDU-ukEY21>`N%FYC8zdT1rX#lAmy=(>U@hF(!1ce7=A+j03WGh zv{CNRzc7I`5=%{89}af13BGE7L07`=KJ4(jZj3ze*Sl}$^=ny=EaO-s2_f%jwX;#H*vI`8~ijKs32beOsbM%~T>QcS;a?%^XS6YJ@z z`U%}-Jk92>&w|t<%Lep>C5Rms|22)mrnA@#^wn4?QcXRS@(ni9G6-f zg9;{mBbYxoI4v}J1Bu@hkSEg$pqT?DpAeIfrMwmP7( z{_V}dT|~df%yUFgO;pE-sxEz?_}@nFE-vLs$jbJ0q^4cwGnuVrR21fqb82gowD;tt zE*0qNY0uR8>S=}U29pO8q;PR3!R^Zy6Q4h0&oJO5C`=8Hj+PYnerdh=bmzYjD*92R zNW|mAc{Ex{|8c6`pyK<{`#TA0w}S)O5G*d|j33GU%kmYwhlQ%1H2KY^En9F?a!b)ehCl=mg(UN(S^ZJvn zEL(7WBgGqE1SI8qut00qvOMcyTM7H$)~F|6{OiiS?k+^grdz6Ik>zB!igg2zrZ%zH zkrKx774usbHWn6B!rldlWEtRn%rsKL>ERPPWRtW{e(y+@Dh*;^FT1 z$@qBY_$@~KgnWzQsKrej23gaZW78+~72gw(W!1{N5sy(5Ayav7_&3$lR<;^z8AlXT zjJf3=JF7+&9ePHF%4h|b9w}w>Px+aF@SzXwX$4{gq)_ zI08RDbsv&I)1BJ;6a?vGanC=Py}|J33qdJKkq{QER|Hss!w-xU=sGK z3?BNitVUBwdOzZ`-jMfw$lpbEq@BjI@z>EB@yhzj{;Y$o!&QsGjMrkQ@63Sf`4OP1W(StU0A?t=&5HoduMCw zHuo&8emTdvx5tIF(Hp3*mGaSY?)ZEB?3aOd(fQ}|xXb~p<(%6cCgrT4-{>8j5#F+p zHOI}xZiyP=vVUFb+Yw0P>)y3vxh-yhfKewe9Y4o)v+QJ@#vzkJ;Ci@{{ny?Z3#6K5=CRN39evI^`GIGJgae%`McGGAjO<@-&p$wo*Za<@OJ*} z8%3x?15a}H=mi=6kbBnb9RqT!W-d&?SddbfedL&>uXewB%78|DgaS**n7+~eTd7dJ ztIqoYR$I(|RFs0=F@usdyk21lC7?BubeQg$XU1nVu=zP0#k=M70r^O!&BO%EwL|CIu;v|mgwcrx-tKQYQz6E=9 zj_;#J05-*?;`Yk@d7_o9j=t4oun6}x0@tl+8g&M7-4=efK5>#j+zaPmxqKy^$-ith z@I?X$k-9m?S^k#WAbj;b{P9n^71Pv#rJ8<(Ik1>sYk&3FxpB&2QM6Ii(c34F&%)@^ zSHY0e0P_lYCK2~pdS+fd1JK~l={Jm?vvm+knEFqL)=>Pbx|G5AEoi5LRkJs`4 z7&@DrwsNz=TfNji)RZtbxGSmFSHdP(S_d6NF7xGI{=1(O<GC1j&|e2 z-ev}2v6j?soEifWDiWl^;TN5I49B-9twC!|Z9!|{0S`}@n6Bzzi<-&{aO}FTc{ZaE zke$^=EWLOz&(1r>kg6c|gg%FWz!=N!oqchsg8sh}(ns+MvjPH@+aHPew#_tB2jVTc zCren6etu+^Kx{57R&bkEosjU{ zn$l$mKLbzVm2JIC-dHceZ~JY}bK?0KdWHV4{an=j*aQmeETjc;{SmZ^^cn7wM7%*= z&fIQ_>Mu>E>9zt!&qIJlIeL$rO;>08qPX)&Nkode!c)VZHh|O2aeH|(Su-%OtwlRY zBz>#Pu=JLw&e}kFNU3@w=vB;br7j37@z5JMh&-rmXs&x(jQ4D(^EBK}SM5@t6e_c7@wGmf+@7VmnG5>dQ;R*Bat4vad!f-PFct-u@x{YC9eFJq z^8jf6l=);CrVc^mBo356g^xoX1}McW6!-#?|5G$4XzL*b3h`z)oPX7G*k;S0?7j_X z+QkTL+MPeZ2<67ea$SjjX-z7yzA_^4_DPQBcy)`p{V7?!84vG*m@y~bE?R-Pqe*A3 zz&tKiMDTKZwqW7H-=qDb<|n!yPfiRG a4lvATx(wFceg4}WIC*JhsY-xJ$bSMNr!IT| literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/dialog-comfortable-light.png b/testdata/snapshots/darwin/dialog-comfortable-light.png new file mode 100644 index 0000000000000000000000000000000000000000..958125c51480e849ff8aeb510fcbf16ebb4bc500 GIT binary patch literal 19521 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 F{|3VMKp_AC literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/dialog-dark.png b/testdata/snapshots/darwin/dialog-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..ef9ee76ebe2836f76f926afa7e06bb3bd2298754 GIT binary patch literal 17834 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/drawer-light.png b/testdata/snapshots/darwin/drawer-light.png new file mode 100644 index 0000000000000000000000000000000000000000..3eadef37fb265c3a7b87681b65913c1fd959da4e GIT binary patch literal 16230 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/dropdown_menu-dark.png b/testdata/snapshots/darwin/dropdown_menu-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..4213dd33b386be05f4183f574e2a51b8a03cfcfc GIT binary patch literal 11343 zcmeHtcT`hBx38!O(wm_4BE5-JDI!SkAT5zj=q1#I-lX>$1OyZWq(hJ)p5RU3abf?zh(a<7H1KIdf*6IlIhn?>#e7S{jOkc+_~eZrvhOR+7`X zbqnh|=KBKoHm0RzVAk!{Egni`IT>BAcgQ(kE!{~voP!#qvpFC!omKKSoEdqW8wAyL z@vh~j!6g}a-1Sk;Ox*6()1OUBS#K3A2|$@b`4iR2Boc-F`F4d*woJ|Pc~gZ$EhrzF zk(9lc#A7A~z@SX@nG1itp+$WAPfXzfAiv6nu$B_O@wk8ml_>cx(e%U8m#P>)}0pBv2oNi)U$k7D^IiU z{9$4`jH#3;ji$w(Zj&L8ycdak_qHh1=2ZOIZzdt$%$KIM_#budhh{4p%HsC8-tm8_ zQyi*s>kse9kRAWLqsd)@;&fxm;YPwFfhR_stv34_x83l z*eNq(ktfFBT?$+m;s<*lI;3<5PUyK9n;1c&on_KqSLNB@_2H=VqZR+kO`YXP;b<-I zNUpcIxc|`C^s}TmuS12AQ!_#Po;(Fv%Q>M-)H!W{Cv(|4ZMf$ z8JlHy9)k`g0g{@OLn+3{jlSm|Msx38PL`Kf78^K>2^@}eg|SZ9k$obV%Y=`nKhTF6b6$@%jC&*+|w-eI?j*`!~Dyx$O&|RusMJf-& zKY+LCNuxuDS{fS5i%+kpHtvh^mWe3SJY?qgyGhLu{y~+OEYBLFLYanK(d|>%%5!vd zd@gb9?d$IQnJ*e#<#XY+zP7>DL2(h2eo=8|m(qGOGgPBSUbx*)E$BeMN%yIutkKim zYmMAl(@Wjct=X^H?bv;-{{A>h~pY6qVrDw&W=iql` zD%`tdzRC-}m&W>EQgh2Ux3-lv)JL77vJUI6S*$0FP|C$d#lviNMcaVVDz}0>WQq_$LrUjmiXn+mPbAJKDY;m@lIKw(z3n@D+M`{Aj$sr`y~7J`+2Bz@@@O z*71pnRWN)uzy5by;EigzCuzoMtdOvf``lQolfdUA!sv?limW@L+Ezt)uCrg6z){}xJE6+RWjj%(VGyVyPsSgx&^O-@GNw6tPMbzfdK<{az! zo0wJ>3ji#KG=PUp^F|@o?#pz)ng%gOm8M@Wx(h+&Tvx?K^_$D}&y9awE2gdKc?6$7 zosu^ERr)G4G3hmn2hsoHu2n^!gF>NO9^whvRhb>Uxw>8jNJJTXeGf;}X(+Py2u}>1 zh9-7W<@C)Zxo%umLC7S&bbE-;R){x>onKr6hm@u+v;vY%a_M>=5G|B`ZRNN;-T~mC ztk$0r^umA{W4ngo=xGVx6diIww^2_{ zR|8-L#(454ZF)?X0)M`lJjO#ge5Mh#XX&(XHLwwFj%37zbDW#9G(C5tWBT|79HEbeo?iU9fVs~zZr-KyUobFGV>S14OK56t=|g(z1(Zq&&x>xjb->5j8~{ z|Dj75mxOpt|sH?!WujE0idp#u&<>2y|;=R{lF~RRk>Vk#F81eXKyMw9A+CvZulBR6pmi z#h_RS4yZdA792BpUA@2T*P=(WK7%kQ74fyq+=n#H`-b2 z3@v1XiZa)$I*Q7n@_xZV9M~_DTu!=J28yqlLLSRn3S@a@b!GD7vLQT1{JU0;yJNeW zgcb@S{L@7s?A+YB=5T;xL45KHEe~IxR0&c!r&YrcHN5c0;L0IwGk(w1$oBUfQ6mzr zLZSH|mJ-5aeJCqJt3pW>KS*^jV6gfsq@`zxXCX6+7 z72mt%#f!!;M$0&Ul3uFoCPsmGVKw($AfL05L7DY{vOJ+*ZV|Z25IIiU8p8JKCKpH4N^f zukX*E^%22IIap;28%@-$Y zJqY}hi|(&b1F>ild9fw=w^AT;p4hPJCzRcVmSuP#*Z1LfgyU#GeW1{ersnJ-V9Bz7 zzo5MjD1oL@s&K0o6zGB0v=;@4s)0P<*2W)eWjbs+g-3yclzKxkH{7LGUFewO!FI(u>?cl(@weHO=y ztD_Jp^;`)TuCe*@b<%&40exO%8c?1CoqVIZUkl`^-1l6l@Q-S1^OS3rWM4L*vv1(-wr-lvzj$o;JkPEVJYf-xa!@qj#=^g zNMBycIG8;v6R<1OwDqBu&t`4mB77ZI7e_N8#?6iR{5eN*eD(M&0A7Dx*($L^LqsCm zg5FbF>3h}K*zqGv6uV$}Z-!ruZ7*Xm;eaiLarL{$v-z77zlI_Wys%Vug>KPe5o=Gq)@zi%?VoqV8p5a){_W8&PDfi?+wkbE|1@(N#D!0- zeq2)5=zhc@m^v+%nxT*+&mN;ena%S@9?1VP*V3==y&hO-R+I;Kx%MJ1)oY$s@j*bNn6OP&%Av`#=|qGqtDXx7moBr zBHxI&KOxG(b2ootwkmRr_?~0#cYmPlffV5>TI%|+Wylx3vyz^h@Kp)^-ywf>IQrLF zUw4=CxnIB;TgK}_&zojYk0RmRdH%iMndS6#7_u;~R9-d^lJI@qfxpZMikwPE-uqN*nDGedylxt_@85ULrN5f9sJ2$Sd}$#oNy_WHH3?%S3?DgSx$W{ zJ!{!)WME30(%|dlntpr}ldp8MB5K)3znW$jSeTpU1*D7G%xtd`PQDpifuCO;G+;V0 z>`Q;XX8=v{j2LZmrSmF16esmbpe8bRu3Z$jmS zJd_Cj22a;2iBfJSx=Yc*vL9|*7kwo-p0qi(tUn%|jWKuhX|BGc_|mfEQn9zay=}qI z8nbqh{%vvk$j2j9&bYL^ynMw)?9I!UQ?DW$4__`L*H7Je83i*kW8>5-aP$luws$;{ zu73l<-HqNE$GZ4<1g7lHE)Jy)_GM*|pTTExLI@mcdU2ozy`7A*CPT<_J2TA2;kP`WcOd!BE|?UjhGl5rqP>@Pnk zcaU#)JbeDqkKA_>?3QOa2}GF0z+pW#4t(XgQQ?1m9a6MzZB#s|nVaPP4cjq8O`YId ztTNp*UVk?^uc^-`eaNI-KF{*HianhQp4rLCA{m>v*%@p}kv8A^9qfc_ip)H*^r`+- zC$r<&BHh-Of$zZJ{i!33jJ8P|>u!dj>`R}n{!@`Ar!BG!9`@Je6O@vd@MD`BlMM;} z`f115^73X&|3m8!!-40=F{6cQ;*h!Xz()_mt7n~vBJwxlA)lTt$b11WcJf5soibbD`FkN*Vonfo7F zBl_2@!CluS#u42g%zARp-kMHD#ooN%vQ#0Rj4L3aPAr)SywG>m1>Kc!jo@axSg0+< z-(Ns$bBt9M&+Wa89(g0X<_;?1UYt95+1T9kPb8h@5L#pPzPwbB-ZVb z`5tKKEA<8`GI+b}x1gb0*S{SAfYG-;(er-kh$uyK>znK*Jx;C?6%nV?!$W#OHt(6S zK2{oiX>r%zwwg;PslWK%W=Qsf)+f`l24@cB(NTG}KDUH_=|90ghJVQGxcOu zcS?`Hn|@^kFTvN>Venm6c1_OZm5(DMXCj%IB2EjaEt_2YyDg&G?99^AGS|!4#l2t+151H04kBaPe&P;NpFj}LsaFOPjEKng${(yq5kGd zj$_w%B3=W5HdckzLvqRTf5@}-@s5kwQL2|ulk{T#-?90 zB0a=c1dpEn!)B%?ph5M^9^Hu>AJ4q-p-bqg zJ@FBZSqs1Xn}nCmGR>|a9o*d_H&LOic?0P*{g6HLvkRcGFm=(dv<=mI82N~lOz`11 zi*b7=C#QJ~%vO(bc$UK=_ZUQ@n{WROoaY|^(rfTlRi~OwTgGZr*pMnStoAYFw#pxLE+g0Nn60olq)b|#yNbUy zjXT`tRK40Uef8=`x7mk@a$iRuA8TzJAI_QVHCyMiEpFC@v+>piu)5I;3{{a(l}!=d zd)aQb31(SYz_C>R(~P+>vvNB+?^Bv7BR>3JQIvy_-^3WZv)7)$baf_6Bx?vkGLZA6 zwfrtc?)%cfPVE1kROzXLczQ$r6$KeBFXB0vS!1IyPG2H)&&NhGCjj-m_-Nyd=1w9u z;CJz71U--!$WS}?-c#hEv}9uqJ7;UwiN)IJbIalRT{)7yV{h_s63IGS-#`zqk|w35 zrsjpPTUNilW?-gNwO7{*`;jC?L*RoBKBj8*+?~@tcI)!p4}9Vd*4IuYS4e3^KyWB9&O&dvQDY;3Hhoe3SL zf3PiRvYP{j?tByuC&9$-AHeH=UZOjCnb#tH1WQa`+6-hiJ&Vf zS>J_tqk~U`O6^4qT2DH*QhGFVC0qJh+F?n~MpAuFl&EWm+2t`g_UAl}()1@2f>B*+3ISL=E(TU)y0L+r(-^b1@3}3;{Zm)6EA# z?`(zajoxBp41mCqpp*c1Zsy?JCfOwyfSqf;jX4cBb7mnS!MxXDBl@+d%@^Y)6%?h> z&MsAw(&J@f4_ZmBiCJkc8w;Jl+0&&rIQ_`F*zzpVW?y7^Q7)HA1=gRblhxUa2#jH* zjFD$fvfkHRs)BS)ibyAPVU~^+H?~9Chb6$Rhcl%SGvea>e#Q(p&kir{l$7|OvCv_? zJsaCXPJ5jrEIkW;{*G4@Yn0#+Q-vQw==bH0pQqzILx5KbW2O?6U{X%Rpy`rko}QjC zWgJ4Dxtr0oxTJ)GjL4xo2w3N4^DJ}L|3W9~%)fx+emDsJn^e>KuHEf2Q4B3{4MBg1 z5wQGw(%;Aj|F@E;p&Z9 zBSJMG=BuYjU(d$t#9sz5Tu-6r!OjWU)5J|f0!@E?*MEC+6g`xr#{p6)@DqUV?NwY~ zs|1^cEpkBt4^SwbJtvI+O~;+STD<Ba8ZFnz8ervuZRF(x7dr_sIA6$#4ju;=UAP-0y z_2nhqRg324^V@N>Jipvu?{bP+TA$I6Rj^b(FFtmn`{&@IaDz&FedSJp5mHK!)MObE zt`-rI{d%A%eM(l!DH1lgz1PxRIFw_!f0M;BjX)3++lA-nckl{HNMDVE{RLN5ZuICA zypIj+X6qE7kP<|;L&6M2fY{ls+@TE-dGYL)!n$B9Lh4;5b*FE&JC=(YekgWd(<-W2 z1O1#N6*|FD9gDnm>8SFwu4x!5zRbV`CjM;UY!~bI_HX*V=~llH@h4AGNp51Xr*~&9 zH`doRV7YaSJ4<_Y&!_f5=UZdB^uOd$OOqx;DJpavg z3e#Pbmy*&!6!E~>?hwN3)XaP&LZ!fnt!exqJ7?m-RfQJ>qF=r@C=D?xrJGKwvQiTK zx^wAEOy7UAus2p+eHa>gt{H-feqnHD(8hXfL7*6GO5^2uMT%0VW{;zz_~m&O3QP%F zbJJulDRp>SP9l7D_zGtA01sgK>Uec^th@J#JF%#4{v$iPT`dlf90l#Ffy+r;NIp0; zJQEjIdHU5U20uxu)49SF?EF0NczrR-*5jo69ER`EJaOPv_p8l5+#KQjPyvKiN@DahiH(HEu zF;^e2k>N!X(%VN$L9Lpe>dhmz6j5?=9=kK1oxK|G{sFn#B!`PKCc!-b^!I0Y6_HPaGbAD>GoD?8rZD~t}am0dB$SiL34 zZ12z{^zjjq_tQI8+l`5CssN_LoN?X}@PJ2ywKs^;VBXOZkH{R+d^ zy?f_uflx)j^j79fxN%>UcLe72gX~p$uE9ml%!0XXF#Nwb9AFcAewK|d9W#Z@5&ClyLxkcL%vR1K4zbO z(T04*E<*mrNI7Qugp8aC*E=_SC=~MtEwN|Mx(Mf(WIvceAUO}h&FTHxmg>k&#%_$B z)0^a)h}i%^-)lJtEMrW0^M3CD-qaYoOm3d~I3MnfY@LYD8?W=@I$We!3dv6Svhw_0 zQml%d!RDaAtG&Yi*B)!3c>&>cCRtfo>f&VDqj@ItT0ZFv-R8m#K zRFs;PXYpS&JKnUFh_1%#=at)X7ZljrajMUTCiZs*|9oLVQ`x*w4A}ul?9uxfe%rh7 z&cUCkSxHJoj@&p%Q!!ut~QL-x>&;5FZa9oF*9?IX|*?L zYao5$;wq-{427yRHlCT8L4Zb!4-Yk^Uz5J969}a$XAE|eHDF;{642Y^09HCEgCo5Z}rKJrxB<&V%gZ_w(&b4MrnTE``WKnmy29BhZ4F|d-37d!`3^!x8XrN zj1otQ^NakI6%||QtL@$EwWX>(3F!R=aA_zB*RZurs0e>-=w!nL>ah?-fHJlH8`C_t zm`omf_@};jFLnLOzB<)pvWv>VLJn$f!IZ5)Kt|5HpT?L&VyK+O|_%D=5zNKhNQVL8*o?KO;CPg$-wK_l9KbQ2_#ZGtr*A&6G$ueyX90~=Krd^ z1Rig3o8a3)P@!N%(Rppu%w!~iox0EEtj*$;6`FVf`K-%g#K+i9NXzc@Rl(`^>XgL= zv`kZ8YUU~2R^g8>%4Rdl@=NqGOl3*#HdEi1xg>6XLg3qn5f%m};6Y_LOfm3>{T45I zW0=}V%w7^cA(o-6jyF8hEn{IMP0YblqGEKQ*(mfSHuEB(k->gAADl;XIa@=k7cO9UkLKC(K=YuUhtUMUzp!`TB#>rw=cNNnTt0 zHAc%K!-=&jx||%u*mH!9IR zXI!j3ZFeve>gS6I6Nx5yZIYVelVE+^ZPjUAAVp{PJTo}xJ)=@85vzFS7Y+JPqn{=p zSUt_aJV2$k|ITqYX=Eb59Or|(Ok{ZM-OJNsazeCy(wxXv4!bOUuiQJM_PVg8$X5+6 zc2ofc%cy78%{keR1sdKT>9g6zPCh ztaqC;$m}}+God8{+=ivK27)`U4^%}wmj+;#Q)Ckt4j3`g-0B71G-s?6##}lbcburx z*NDt&o8`V0_q(qAWGT8KfWeW8%EWOJ`(SNug{0AKGZXOMT0_wb~ot^R#vK2CMm)HX|H%2U`K=V${$!xap8LE=lb%7z;zzhCZd@6mbt7p}@j_!jzTy6|9s z=b5vFJZButES|n4tN(f~FZId9!0P*TTd843u)>#pd_n_{P181nAu{-}yiILmEg zoay$~mgU*V3qz8Lo6uc5s7yj>`;)o)LlcpO0f-;J#8l$iK*vuWF^RhfdvolLkSZ)D zN9nZ?$kvbcy}OTaw`IJXR~n^KH|lbkW}|>*+TQkY{rt{O)#2}Najh<>*&)*Of%rdf zH|Vz&;C#Cm{$?j}V5L@*W(ME6Y4f)4%vhQz&L7b63@Mxbnm-Q>Gk-{w92VR{C_{30 z8t*rR{{yT4-A^;Yzq|Yo`~3gL|5$eahg_!3WKg+Sx3JL`^a{%Bm?OitZYj%a$W_Ri Gh5Q@6eV76O literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/dropdown_menu-light.png b/testdata/snapshots/darwin/dropdown_menu-light.png new file mode 100644 index 0000000000000000000000000000000000000000..426e388a89a43843a3301f76eadc8c819263c4bb GIT binary patch literal 12878 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/hover_card-dark.png b/testdata/snapshots/darwin/hover_card-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..8de2e5ef94f80359e844dcd3d0de5466072bd838 GIT binary patch literal 11983 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/hover_card-light.png b/testdata/snapshots/darwin/hover_card-light.png new file mode 100644 index 0000000000000000000000000000000000000000..1efdfc92425ed279a5458d3d41b30e46f122c9ab GIT binary patch literal 13494 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 O0i=G&iIs~O`2AnA*382I literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/overlay-dark.png b/testdata/snapshots/darwin/overlay-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..48724cb34c6a2dd9fae016c3ff6d05de79e5fe91 GIT binary patch literal 9729 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 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/overlay-light.png b/testdata/snapshots/darwin/overlay-light.png new file mode 100644 index 0000000000000000000000000000000000000000..28c30609704f116f853de6d3bb6e03c8f65668b7 GIT binary patch literal 10907 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 W(Yj~9O5ryP0m=#*@>Q}HA^!u{(n>u5 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/popconfirm-dark.png b/testdata/snapshots/darwin/popconfirm-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..4f35c901076f53fd0d1b943ccab7a5b279242c76 GIT binary patch literal 14906 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

Wy+KIsLOTr z^M5zUhh|;qeg~v5r>NZstNDG2o&o^KMb4c^Oh_Yxy_TcCjId~eGS=)Zc}_i22ctJX!d-S4 za5ipLg)>`}v35>8gup~w*!)|F`~diBWBqSImpWR601N)>;I@bFfGY;U8-Konk&cNy z*fwuzuTW!lqX7v(C!C@tn{=v`WtCdlr+relGE6i4&Wo?L6d@qb=G9KQK~&kz3%b-d zn^RpF8f6G?>;Zvo(}!(5b*i-piSh^On5Ask<@CE$^+>Z+hWV{xB=?Ir8%+b9ZCMD} zeGHi_(vwd)6iD~~comW(D?e&q-~h;h<-r`J-}49R^sN@(q~DSyfAy4^4W_7&Y^o|c zM&9j>&ieJoYE#I-hvAu+_xoFLk~YngV8um<1?bcM^r z8@0xJFh`V9b1FDsa|Sc{7MnS15|(9^z99wg;)30Wq?3_r7a*(i$qHaxI|ZCpy5JOs z)fKya^LXqL7SEM$nW;JUN{T*(XaE&1>y{Ju!pw~Lk#7c#bA+)cv69sJk#=s8sP03l zFo1E2@*4ZhIfe9YJd1P&;LNOG87fj_5NgqrE+~YY2E*`Og~Ai}RP$AYG=KweHLzP6o#D7rRPP=4PL8CO^w$wA z>1ihyW~1C_`~;W(qJk;+Q;8E&ojb%rvsjmr`w0Nhp->R{r)RKI!hmUxOd$U&vp!T# z)-{-Mx=$~gXGu?J1sw7~E*w!yuw5jNDKNmdNO|siiTU+<#t1_btJqc?)s+m#qP3x6 z?it?ZT=OHGC<<=5iSGx%cMgPxkpHj{{ zDMHGG3PA(z_Q~yuRdIn<#igotB~bcxiDHi56ZEu*-3_Pcwz}{DHH0&uzwe(4tUj+k zK*p-^w?p5q_%uqOo){{$Q0}9{F=X8rw;tqWNZ#MDpa6pZznpB$4aG^IyobNzgKE*J-p zLxuCbocWMp0cv8*VS)AU+DidbjG|41Jh}1Y-slX3=^%q~G%O zP7!!?Y;ZoRq0ivHo7wyMsOaaYM12yYsSEJi_?iJ?;9uFh>5HdyZs`6SfAwAADT30c ze@^8oqI8JC{_>i&x0D(qidLgSKKE_vt}Y^F{wEQU0vTB$x*-1f)>eqXwPRA^^~t;U zpdC3Y>zZ*D@I7LuF_0P4m~K!rrhbFS7@p({EV7G3ox7VG0!m(5PR`EJW#>z9JkL}D zw=*Uox3VN$o6m{#a-+M%a{R+hc0y{CT(RKaUd^PPfV4#KxTEVKX4JGm3(?2#vR$k5@1B&Ppv(E{ zNp}LEkt--_fsA1N<^};!R9U z(4^9k8VQ7tt<)Ljba&fppNc15agh{tb&+s#8qlN;4h}eQjjunFx?e1JnphTfcTd&m z833d?*w_{qHYh?cuu=zWU0CJjhP3HV%|UF>v?ea zmXlDOu8jsNYrAGwh>?(D(WEvC#BMj%_14$*_y*gpH$1NgKJWzerVgCGAt4=2=rua3 zQ~&_zB>S(IVn2SQzrA&wR1|e|1dSa`X8)i-g~KNxSbin+%F-K~n)2Q=$1yt$etYw^ zi0>a9sH5GgNUh8I*DIVTO1c7gq4Mx_QsjHQ|M^?ocdV-`@2d#|bUrAI{CXlQ(Iw zaN&6${~R2o@)7#KzaX75kSr{)bJ}mtXGGA_Fwko?DBi|T?!`LcdY;ZR-gV@D!@e@| z_3c}%vIURJ`J||5Zf>4rH5s1%SLG6tFgiN+{W~jm7)i+8#m1W9e#C5&vkOv8{eQZ8 z*k*p%9Y6>(w6UqO6wzC2F(r`pi%gs*xPOll({+^xyLL>9= z90E5teh+gE4R`O`5?LAAXe|9>8E?^Y)#j!q7+BcQ5Lp|W4s>iL&(9BC-q(u_!ql+? zaq+O|LQJ|iZDI^U11700{Om zGvm-Zi3htAQ&Y!_bQm04L_5oJJo2RWN{vcwZSAia8CFvQMyB=~7ks08{gFgxXLvQbUD9yOtgH)b zMYYrY4+J_Pe(}UtKuuftHdv{Jnk(#>BFLx_ZQKLV`G%VeHcn;3a?$28! z1h*bc!Q=M#=Mj$>XIYn548a=EQ&?SL{zgW}M?uFoxZ^-qO{c4uBO+32L2t|`riIiT z6B{e9Ftyr#f4kY~{rch=8Y;Jtd#>&8g6(>&;p)5yWUbNfhL~lEB zgN;5qdJMb3Q^G~cbt0QxPuH1@pWpg?l}%^Okc0$%Y}8=_c?sk&AwR{=EA9r2A{10& zQ5J}NrivBtqOr8Fz<`Ts)vdXRlwb%Ic6_u0)H`;6uFO;C$QYy0fPHM<)a9JSR470M z7R3PgpfjHo%12n+*}1Vs+cRi(JSbPbs-#DgYH8nLAw!dTf4U%Z8KfsuuFAp5i3km~ zdhDi*UVz1*BS!R}puwi@|1epj)3z0K5jJ(S6`#3TBF`V?5`rqyhjpB9r|GHn;udYKofCZ9aUi4 zq+T2KtH4Oi6kg^hWYX4wvy6LK6HGl?3dBs~1DY+2BaR`)o6O4OvJ3dYa~Ed~w6}guWSnjuHvs zX@}3wCWJ%W@V;Z&Tnfg;+cR~7vHAK<`01DC@$o#4w_Ekm%1J(QCCpdQw*ZA_cpawe z)(Mwms%K<;Cyv`88pmQ`5(!J(S*4*4Va!*pPV7C0R;bd+t}n3p&{bHBa1$Rdb1|XY zCFnk0W#Xt)!hz;V0II~$ZMnCEdt&Im+TDa!zAYDG=tO~7CPR@WV;>*mS`MNm@0^|L-IBwPi2~G<$ zLQHku??qo?Ea{B9??;2^hDmvAO-Q4Q`N{ILJkkbvYch%ozsPF*`6wlrr|!gAu5;xJ zmOH}UM~$W$hN8ngO!*)naLyc_W7jrU>e%DRa!E)m!}(=+qma}4&Ct-$GHR2DEwF#q ziboVd+O%F%cAuo+Bp~bHss?^pXjoQt4#`x+f><17`ZOPo-XvSAKRjpxYP{cGKy=Fo zQ!8U#*oq@fl;8klNgV%`kLOjAT1Bzn$Z+UMmg<37vSct@n55F1p)z@XtSA=g9+l>5 z_H9uwGv3sZbXaViBw(Vcq4{v->ZzH}kFv*XErQsXWzjCbh)#&h(gj)?4h?7jqfXt~@9x%)=U{#+(*?qh z3#wFQiaBjv3rpB-qk{>c+fkt2HH9R-JVzl?7Nl$lc#{vnkI}CHAB~;{)JaTmKTZiQ%Zub&nsg-%szV5*wC<3cIC?U%v4zt0ixZzbf!1|Uzk07 z-Q4rTj8Xwd{}+CCj(O*5Pw;xjTpYt#%3NAjRA5(G2(#%cgJH$fw(RsAtri)A zan%dVbcGNWlOWpa@3rDou4zy~MM`rzv*^@9b2rhlsC#y|Sf1J9qb~~Ny^&_w4+c%_ zs!@2P!t0yf6li2%Qx`B7$kUxHTGA5~YO`9+w;N$LOvYUglKcg_vMuHZMZy-*i{MFqoVcCxlobwreX)eicdPh%KL5r2 zu0T^$(^kZyBW}gUvMVQUuqICLMXkGp?kqGaR+q>oq71(eY=Ehkn^y!(6BNb?8x)0BQ`x?-O+l;TT~xfr z77A%jhc^@i%_U~)p#iYn@3pfpgDh!@%cC`a7d+LH=)XB=E~*d*)4JR=f5~e5dgX}# ze;*p@q=U`sYqV9Jc$`SW?OCnPv|H-?6j>aI1aTo0ofsGe9nVgNL-$ZFdpr8T#G2&} z4Paw}oyn$?V(nC%%bNL4Np*LNII%~3F{8eVW9pOv61E`?w@3feoFUI6ZD$+~Q(}8~ zWy{b{F>1<^Ql%3c8;c}K6{~7&ya!sDfrpQz`X}2o?{_>p%9EV^HZ?m-NtGXK^(yFI z43ZaP?yab_-gknDGHkLH8n&r;!E3otl?liR?E6I^FsH}U>q|R1jENNmwb;+~;38qU zeUZQCjzS>8yuCcf|64AmRZ%rNF?QC)+Q*?)!N7mPcv;67lRk>uk1u%`;%{^FgY-wO z;O8A8jdh8(iJ(U9M_N*n+a;lA`TROS5X^w@%|7+0eWA46yW8i7$SCpf_&6@7TQBkF z&X@NvhG(kgk`m0+UaPa97wsx;`c`8XW5{`&`6v>yDeRIbSBQ1q?B}R>tiDp(kxn>> zt6TwiatN?^^{=nn-MIiu^NJ}Y8mwlb4cz#K^~bxRGTbX|Vq(3^%j8gj#JrTrQ%8l$ zW))%&w_}W0DsH9itz3_%3jpp{Pc65-!HL#oHA2D*W@e&yzw?)qIc^&c@3kd^e4naj zssdK&H=~$LC-!Bvg$Pzw`a!_lI4_^W1D<&&ILn~R5TDy}Jg1gN9UX8-6c-jQckg{$9ZB-tviwyQ*-u#5 z$U#w4d~if+M+Np7#h~8E)$%0y_*e`qo6u1Cwv=>*J7Daxf{@S-Skoe3z7>LwRtar{z}Co}TH20-C5yCiCmuxAFMgg!mZE=2Q9*J+sAQ!NLDoOiFQ&_oaLu zk154>sO|9#!1wQ$D0g@d^4tB4i{$Ja98eHW4bI@9ZkN(ISWONIpI169b{eXxHJbHa z`w>0ev3V&uzL@VKS9d3Xy1In@{a8f7n9W8@eu(WQ1AmDOOi0vssdvMBS*J!6NoE#zm5$k4mZ)tIXKTp8d z%D9k^+Hx!sy%Yi>{?m&NBMMD$YkT{6dYMYl?XG`cDiMV!r4`uicQm;{F0&f}v}S7} zYSR^P9)#`wbmOO^D^ei3M5mOm)=do1|8A%UZ0G4Dg@9;nbvaqtLrVDuM!^_0mx`RHAMUdRL;U!NIL9MqXad)8Nn_KT^xS8V(HfiV+QF3+63VuUW@`yqw)O zorMZ3d1`S(Y%7hBy=%Te8LC5eJRk>S{L|DLzt}cCc2rO)_!^#P~m-|QX9?Zag z4HDw&77xt7x=w0t*oeiLm$d7ZU6lZ<1J85^TUwhF9w$CbR^_H|2L!|?(A9hPr|akA z>ZLyf1S#28bS9_yFHi-`@O z5T&`CpIUhc3g=7GVRk>4TvjLu?l>%KmCCd7Jj~2ES5{gpyOmC6@&|uZm`!E0*{mdu zN?+@UNNl~`rs*;;($Wh0(E$wn^X~30x$)(trL}JkYn`V)*i5aUE1=~~vXdl#vYN@i zf&dC6A-4sXxq^A&EUsg#t5)wXO<&%(Kr4W7MJfbjgt2a?AEryl$@bXq&YMiF}ub#h=`RG2r zulce}9(95c+ej!zy+!tUo9gQ7G|(77evFyi%UzV_=kGKvwd;5L8P5;9hanU2*{vV{ z-F7SsBZ!!1Q3|784SpUrmjMF%=oO)^Z62AuK|P zN-LsOHC>lLVYmcrX;Gya<8c+I!ce1r)OzedHVtwNGzNh{5tao(-Vg!x#uA9oAw;;} zzfT5$Gox*9ZNQKX6Kh<{(XzkdE;arDvBTIurL>VCYqySpo-LU-V@ zI!1TTn`6v*t#4>}dE9vit3D?iUjdvD1)~Sn_$S-~(@$$_Yw^D|alaEfgF6AvSms9z z`kj1aq`jTq-ubxw!BZ`e5R%2pq{4`bC5j0$A{YoaBBR4x-1JWB+NPn&sV$TxX(yFX=)64N!9cXOxBFx? zUW^sFURP>#aGKt%*~kBS4!Kuz@=+Moj}*NDTk7Qlfhc#tR%Fj&4sXcW?tdwE{-Veet3A@!J!CShBZ2oGm|*nPU*xG zr8j6+70DTZIh{_&DgAVCnab@f6i3SA<9=(|s<8z6iDyo}^LgEI8Qrj9VI7gn2&C{) z?jJ5rC;^BzBu;XQi!Umxs&qR%Af?SlHws?^Am9C;FGCN;_IzI-WfTP6ULSJy=?&W3 zTt&osUN05+y?&B0UfvLYen$um5-3_;TRXccrmfr)L?Qf~^!FEtPYMLcU_tcMz zAsH@4+gBdoaBTRj$h>gZ<;9)+=w?!UVC1X_e38wQ8)8Av5A2hi8=N5_&?!G`U*k-y z_@cc&hTh5&BKH{e+R@Mfe6(k>7RMo>MB-oMP{Qd@G;x(~(oVx3_V(r|NeqisX=39I zfR23{_IFpyUB-y3wB_}CgU~QAi}UjruMZHmN5|cTRM7)38mF9KX$rpQf%^MnQ3&~B zVqZ1y-KbX9)(D;i=t&GsMMXW{P7fUO=!zfeej7HTb@`vmz1l5b<;TS#SEP4(Tti)M z>bJEC+DosZ;bTNZ&FKf+{5x=RzgS<~YT3F!-;vhi+^!k zd1^ElrlPRB>GQ)!C~t!LQE7(P@0Ys_@S^8qS`vpnv}k`nn|he61+3T@xhCIaJgHQ>D%++~^6sM4H7fYs zF@@;?eupz&n>>)`($LUQhAPn0`|cheQ>99qvSfgt-`ELMWv$TEq%mA(|Kb+m481F9 zjS0FM;GO95Ft@d}6(6KFtdAH1T+Fq&J2(*M659ID6;>njV(M7_JXb|Q3?g_eemBnq zBOlIl7J>~80078hCPNzl?*ub3*Or5p>kRuAbCLRx{}-r+{P*K0D92M*MPqfyUiep1 z0)_PWFvl$gRj`p@Qt4dL%5is8s{|Up0 ziuQIflGu3qq*#{ax|lpS&lF@@~m)&uyGOK=4W zFo)&i-ClwGU%X@&#K#*dOp+`e{-HvJkwfs7Qe;xE`3AKD*}3}?jM53Lq$Q_r16JZm zVZ(xBtD>hh8%!B8U;IiWo0za?#D#-_R5wBL2QLh#JK4*3Up(aa_~^LnyL+6mIC1|l zCl)}AtSksrF4-$n0j%Vuq#c`E3jg&J+1YEnqO#o5(&_;byQN3`(-==i@XBLd@MfC# z`K|RBJFF5>A4O1KZ;1?zd|*JP-$=&VdcxVb?7<_J6auJ0=tj7ye}!!X(5zo7T(n)O z+9IM3GqPJ;pAXSxXKweVOx!uW849?V8gN}+chB?{4#5;Al%TdYI`UY~}4Ixg*8 zJu$|=pB10+=@-KFT%?BQeC&@fZJ0Qj7O7h6;E^Q@y-KJ3_)%Iau{3NZ#p%U) zNPDI>dXm)d>GhDTmge)9Dr_k_!{GhV;r zVbC_Qfxmz3SNZxDi74fdu_@n7RB!9cM3K=iaP4`2RCUxkpZm@a$cvY1b@fo&pZtuJ z%_YKfg5N9d&v>45cFd>#ou^6{Z~1syoZeZo1|JHeVxW7}=&13+MOuADTJH zjFVSxk33(VFt9MJ?t*10qT}1Nv{mOf7Hn;;fj0NNU&F!*`COh}c7ud7RHcol)2lRV z<}StSt*nxF_pB?eWhILOGFTHh_*Gm)_or)s&a^e{4N1R#vgqnzhS3LdO1^k~VtufF ziN5&*dhz-q5?p*)Rm8(1jOwy8pTUh7#P91v4EJ)r`JP=Ran47$u@EXsv81YQyYW0z zw=lTlSQt-QXZC1Ty~3{%>3FSDs*uHFEUxA$CTsE&T8K39IGpvUwYr+*6U)rh7TxuL zhLsbm&F7ct0J#REJ_`p)D1*T&J?Q0noLi{$SH9w#!;4M2B6hn^TY8?oxb|u=@G*s? zlD4v-M%UGQY;R*CtBz|uzI5v0{+|A&n~5Ll-{hv>%q$aBV1P*#o1eG$)5@)|slXWi z$=#Wtf#u$Hk@891bC%AZsXx^*qu5NW4ujb%WD9b}iN~)hrPEY*s}q-<2j>Jt&VY!F z%Y&n{UxkK_%VIKp_}STE^kXTq;`xf>lwUfP^p$5$@i3}a> zkm|RrG94Gj9pvsp0%{4sDiwxRiV`#*kaH5?T|=)`zuvcoC@w2!n##iQG1npQH#C&@ ziAcx~C3MsW+ui2vRS};H>wY!?Tw|g*gxP)+XQ?lmEsDI`XWunj346=t+ zuy|pzJ>^|Ee+tTk|K!_mN^@~tml(2*k<~@FqV{K40cWZ9klsn;k2kUCV}?l=Ec37| z+CWJ*HWtz>B~4dX2VWDGl{#B6#(JhC*1If7V<4zqrC1u9n_JkZrsN4W1{yC#u~!nD zj4q2y*Dz;*7v(B1&!W28Gt5(ZdYZPT&cecc#K10LVp(T(tavHeB3O?PU@WWEZNbbPK)=6d zGQKx8BVKJVuLi zHmrb)eB{2#o~IgRKsJ1%-HtNFW+1d#A(LnrZ}J7gneyuiep`s z{62!F2N-915(xuSt8E|pzQG0IAIqbt5dA_`RZ`|LegK8&bgOHq-aXvy-rtQ^(#?H9zTJ3)SZq<;h$`bB$His3KKL%|($R(YxfrS6lYU%8Q~Fh~pbtio#dUyHWo3n(zMnH> z6eZG>Wi=&k#8H0sjL7kMMC~4a$GgH5tZ$&_%nBOZU`WO&vNnO_;wD$G)8MEE7Fb-l ze8r;DBH{N6DtZEr&%kX_i} zx-u+Je9_=zg~BP@3fWLO2nYx=R96QNdbg09ZrS)vkusF2UcM$@Zpss9WqiNCx15aG ze_Er$@B*XzD3Oi{f5D$De=kKGI87>yO}SRqMk2Z@x*c*s5i+u;21>1XK3`webj#s& zWzWuNAa9|dOS>)umWvx&geWVbvzc9uCSC6Q)Wzzl)dcT%71x}$V$;oJ^OicRvuO)9 z&?3J^+TtR2e8ZQc$%TQ_=G)b%n+)UUG`D3XXb?Fl);pX@H~RqLIhBa9L943b<_2A& zE3VZAo}2q`i%$oUx!Jqhr9f#hIqmx+suwoc;7 z(bY2^Hjbqs(+UnwT`i~0hHA#6zv+6z-?13W-$d{IrpZt(zIlO~&IVv$sxnt;1@$}JkB~8Wjmjtr1QJh= z9rmn5EtMQ)ROT23^#tCY1(e)5HwLswG?2qyc+~afkvnpkR8RFJ++BqV6|eqt$KYVu z+?~^w;M~v-uV7#-4FM*o@b%Gv%k^bBzt7|Cw(wthd_it*E*MA6-qOOdp>sFzPFC{& z25w7A_HN$=YD$e-$4C{$>a=V|MZG)>FCm2XCdwOhI`;LjN62Ndt5Bg9{UjgIkDpzf z$>kSZ=Ik-ZSA3fKlZ%0shw43M7L^0Y%F?XL4uk$WVQXoHEa)xIkiK_+r(WZ`G`x&G z`SZbRzTBT+&HIT~1p#J6r%e-Z(1(JUA*(J|4all2j=dl8_xmE0ki+k~{8q0Cs`3=l zI_U;jojv%tIxM%7c+yUc_xg-P9Y|eYKcXi$HZ^T@cK(i!+&Mhl7JWS^9dpJSM?uiy zveCM#^(>1+uFBNbKyl|XE&5tvB259yh#(~;KRE)1m1I4BJ`cW&zmpP#fi(XT<^8iW z4kSxymu?)nXmzp}46#5Z6Uez58Y<3*Pc0T~UW*-nGb^l~%B}ADUQjl>as5ti9t9oG?Y@o|Nc6bI|; zP@r$9r>vjEP@@*0f|h2U@}y5)#~0(osJP>onvEUky4cirG@7ij`xFi%Y@=#~be~0Z@iegJMHq)cLrb zmwE#5D1SI8RQj_rHQM2#A%uGH>F+^-li#R9_8|@XPS5qV$U2%j)hn%rbV#aF6v>gI z1=la3A(B6PzdgFJy$DgHO8-Qov#Z+SELJXW)!=LN28IZCa-O3kJ-9qb6Df#{6xd~)XMSo(h?IVTh}IGhH!tLTU{`V;spO~uz}2;Zs-Pn!iUzB%C8LQ-hQYKn>3th)({e6E~-o7PJ2|O_E8%h-tzKDmXyddOyVL! z5lcSg;r_(yv4i>z`)&EN2LiZGabi}Cn+TuW~zf0#VZ z2H7pb;LmT2VPR=Vfrsn)^tIJnL2UMGISWnK-4R{^W{vJkiKyi-16>k3U)IEv}ttbxxU%^bx@cgO}Bc*Oo$wAia|*&URewghEbXa7W~@9nHHv zTfl})53;PW!GdK~z}7WxGV-Rv#Oh=hpzw>-bV^w$@9|S?Vp*~4G&4Bv+c-l4F1bGN zJeYNH12m=`T6ZAa?5RKjkY65zzy5~(f0;@lfup0R?d@Ls#|l{CbGU?lT0hZ9;L)iG zf^rw|{Yw{QBnc*Vf_%$@_9&${`Z-#7mlAL%ujP`E$MBPZ;*9wxd)gb()|xPICi?cc}K z%Uky<9tSRU{H-Bz9TF1K`{MKg!)AKD-XgI1v&`OR(ktrUX;S9~bd~u2Pq28v0t)H9 z==l(djC60YTf@iZ(ql*-7$662-e<^C=rkV3I!GN`r_U}i9Q;tj_;`{rM_O|_Tm!Q_ z*?BdUg}6v-!uSST`ZZ34IF!_JLY}!BJ?QW8Uv{G|RBrhHDO^s+I%^x7cE`O#a1kLr z1jz>V4t_$2BAt?aBiPXWOx?%h>7ZoLOhzVpLWd(HWIUXh%0vISVuAKz%U@AhSGptt z1%G+(>h5;7@E+tN8e=zX!4)yl>oHUTrYA{HQ z=6NtLGGaM;l&?KLx=~%L`aFNd4ZdEk-(;Dt6(ARpK)Jjhc`ebeS@qFNti|R-f zHxn}KueJ@wP>O%^{!$Sev6kk3Xuh~{*YoKkbbTM7SO)XG^i+lA&(Q~-%eAIfe|5t! z*Jokg@7Ql9Xp!aV);lPP8}!wLM0RBgBX#hZasQ01(UtLt4n58{gG&FnEV7&UdNy=c zA(Rtq0=`(g{hqMnTLekVj1t4$c(1`qDX!-71E+FcQJ{syLI?8v8sh&syzFitnVIcx z03Yf!N5%L#fICn1$%KSYjfVaPf{LAm)rlyzH8Lde}ms_cXgJNI|o{Gj2zrd z%KwACy!>5%>VCet1L}R+?b#_R@|ILWr>m-mTwD%#*TIzKSw`q1`#i(c%}WXtE`(Ab zEDD?0(^z2V8!mWipAztgRv^h|UWKM*UF8KgA$8uDXK<;YUrq^tWic4e9rPj|s;i&% z^fy&2X7F#M`eA!mG6~#lVZwNc7cTFdru*EQG!4ZGI(!<&Pksz9*N26LkV3H7x zqj{dZ7>8SFOW^6dGS>f|cHG-vNln$*cHm-J!H~lKnM8e(K0KD2O91Y0`1Lh=VqL^J;WjaD#}6h-&A|yNm&NPEJnT z_>)a%BjDasROsv04g=B}SlB5sgbc}(3^2318uba#q6je1LN9KMCPXcxfBLIxQ`qds z$8#Kw^6s+(PM^RQrhOZAY5R=%j>uag zWPm152{tB1V~_4^Q+=QIpF*RKdAU^fOdm;GpUKPp1tEl{e~S15%Jqlk?6W`eIsx(Z zyELCqo)>3!SQmDeUuTKNbSy?2-Yl}3yLz?nP^@LEN}{ES6D)qk42oKpe@}*rB5#<5 zDv=YaE*V6dOIjwSC_(Kn3FLqppc#<#JPGQ#X|O*(*z9C<9v}D3&0uvlzZgq%dYt6j z3h#8Dbe_x@%U!u`o65*wO*b5>d#(Gulqne#XV$P{LwD!|?{u>-rBSQ@dJt#+`Z5_G z69Y%Wnh~Q!dXfG3`63#@gJf_6|MHW(8ss3OuggCQ3H8JW6fQ ziW+P^BVsX3^UiB2&*fugaRuUYG`XKB2=l*=R(gn;ehSg&DNJ@2!T~?}?0;lQ} zGtN1AN*5HJM`k7EwQ3!pbK3tUUEktt>OQNOoLt#)@ED3SZ?QQc&(mzXSxbMd1%1p# zGj=wbKY)1kH{XK@y>#(B4l@jteqc@HtdWOsdEIGB45b*oZ!lgy_Xg)(X0El_Z+(Ol zeaJI=$QCOv)s~hk<)lu+qDH&M)=O0ek8{n<&EbSEMr^p?wGyiF`LH_0VT&p( zn>p`ywS8vaas3D$ik{W-qmQ4FJh{cqeQN8;<1z%Ee#FG-EUh$-NU+}IWH%I1u*r37 zu98R#aGFJ{Tt2@##Npy1`#fRaq5|YOn^tJ%zdGBTve9$5dffb%Y|h&*$aCxbi1KkX zKCra)O^mFs^yRQx6F(}1HMmc2%=;!|#@U}=R1U}O8*iB2UXMIny~~LPEG(>h=hM)U z|0nGGx~KKo9^TU9osSgCb=UR1@zADrmyH+~zIOetwL~2L7swYLNC>Og6C=MhMh?Mt zuZhR5R|}q;3~uL_hx4_}%w1M9S^v`$N>01C=Ym{v|a?2xRe4bWy!L_o3o7b-U!i!kJW9>!ssE}~^M*{6`*W-C$eLplwu_sop z+0Q5~`t+q?Ms{j;t#Pa8Ag`s|w5cql`^?awG?m%6P&DHg;Yeoe7~Og(*ZaPXKZ981 zM@6Jaa?)~h@eL)N?$5eQ5(0A7T14#}wcaN8@p*rBCwSa1_#k9+R)vt~udcv757u^e zq!KU(PHiqc$&#`^VXaK|J1y9>-~9%!tS>rVA*C0qN=$U#7W-e1UJ(lmo1sX0uem~q z^Cp)&_GD!~uMx=kU3aenBa=(PuS%gpY}1DP+M=QH3)mS-c(E)h;cnO)uDK@VRROnP z6c@==SHnxI7nhNYYS9dAwJMwareb9h<<6469=ZvCva$)N8EmMBS;78KRRn!;V8Ad2 z_pJUOPH(9}J?tY!^|&J28HUT;zlRbDB;4><98HdfhLLGr)~)I^s~joI5*Uw=pg>j$ zQ@obC+Fbb5-34Q?Ny=e;xh+9qq=u!m*y`_$$oMO2SS$6h*48r3k2#)0hd1d(DZZr& z&E#t%JE~)!ZGwNM9<4H*vikZe#8cH3!5bC}KE!3axQ*NE3tw+HBot(;OhGJ-u)f4* zlUIHsonOeMhja!myY9dmgLeGvgW`P2R?|^i=d}CvZEkF6U)w5Q%PNdk9(4d?Jp1CH zv>e_}Q$44f^Uahf!6aeRhH8}R)+>|9?XM2(;61a}wm;yp~+ zvu{>rB-zCO<*=xB!nOdHTI#+im1C8y4Z~WH;@XcEsi?*d7%iw|xX|F*Lpetv7!tJ| zJ{6;d^C7-L@s?eAuZ>O!%ySYOT_4V0LHq!h`n_n_`B0-db&6Qgg;Tznhi~;Aur8}{ zyz7HkD4e5+7hwr&Eks7$K_y>QNK9*~T)XppILzYW8EiK}A)_C@l%kjkI?RFXK>mOr$?or(jx z9LZCr_h(y!!rH4i(F5)OdIzdeqeP8oJXGj5@vWsWil&7mLguWA&r(|DO>^J<-o-I)~&E6JOCbSJ!TGd=pG|keKX<4sur26jD_4 zKYd7f4tAg3xfklqF@%BqD>X(=x3Bd%PQ>z>386FCT?f!CtvFtgDy^IB#~1fA3(wF~ zv!O^`se@EB7KG!kK%AXfT;LMl$DSc#Ce0D6q^c_Jf!7dU7NVqE)e5skE8KV6{IvjP4*H%fq?BeSM|5cVKF=_GnBKQ2LWMdBsa_*{C_zJe9knMRK#R8a>*Q)Hs+4u9TcG4!Lx|LLcIXLU71@b-19~vKl1hW;;z9Bq5>};6& zs$<=yugtvoZiIpfT&wAFR!`x5#jRjG8wD2GCs~oMK6tQcflv;T%TR{wp9kJ{1a++F z5N>hQd;n!CbAgCDKwfJfVc%HA6FKiFJvru$%`$5+@2PsIYv8d7M>AS5igJ$AF#8?X zNy+wvG`0MkG`~=Y-ib*XT*MtsXK{b)Gy*iws&<3tJjOyWB*?^b%q1_$k1naBW5B-+-%1zOUnWXlWvupHV;jKTb^-fUNW6q#(7 z*O?7zRPLYx%Kskzn8 z5z}Tl0NO7#EMM6_^6NB()X007j|Q1yT_g8K8)RYfL}po4l$sXI>Id_F+qha=svC?y zBf2e+O{r~Xlvh(n58PlH%MY!`1`^y;u~>YYH#Rl~&J4x?u-$_VHKh4X2m$dcLm(gy zsPd+fpzmVvpZpKUsdrS#bk%!Y89YpDAGpEwf`_zkz$_@>De~4b^0wwG*m)Dv-u=r2 w)YsRuhy9-%|NkWp_`g5B=nL5R{0gz`Q^Oea4KEt}+C7Ann7n9>@b94i0f7i1tN;K2 literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/popover-dark.png b/testdata/snapshots/darwin/popover-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..9cc92e88ff365be11fdf1c5880d3f2b840f9e0bf GIT binary patch literal 10984 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 Q{xdVm@73k2WGzDfFHEmEaR2}S literal 0 HcmV?d00001 diff --git a/testdata/snapshots/darwin/tooltip-dark.png b/testdata/snapshots/darwin/tooltip-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..b91ffc5b3c367841366a561ace8f3b3c82c6c721 GIT binary patch literal 4404 zcmdT`cQhPI+b4pJ+^~q~VuO%qLG+d=t9PqLiJIs(qHSWaN)R@P-ojczlwc8MiQcW= zqFg0v^s=#nck|tU@BQBMeSf|0%yZ_4D1BYE8&oV*BqSs^G}KiLNk~Ya z5$A6KSBT?0PktT=3Ghrq<*~7U=8suRZDUi`&i!h&M~=1;iM@Pwc{$)Cl#2Tv5dHjX zv6q3IF|8|FJ^!IR_nT0NT*!nAx+Wd-Jhr1iXY2?JGoUc$i%#Cm?}#$o3+}iN;A@i_ z{4hA*u>U!uW+U8;iTnZwtC~#DV(>T--qM+9?R)sZ7^tMKmN&`~OeXaoCG`~4!rP0@ zPIhBc>xBSBPPy)+{DTCB4ktge67eL6bG7uJB-DTI39t&x4RD%zn{4(zD%0>k4cQ0tm zx#2}Z`G1tID$+<(-tx))tK{S=7m9b}UU|JfuPzo_bE}cqPU(u}*2p-h>_b9srD^?z zc)iX`JA(x)4NtP(g~2()=61}g0}p#{3(o8!88qm`oExV`p!C0eAxG9V>IU(VnVXsI zKauqlt(w4TnqfqFZ6Haxpk;d2-`k)108|NY4q_BOKUqA%4MHYe zwn&LqP!kSDizyV>XBRTj4fLI;6ylp^UQ zeLx+297kp=GI}?wOhEHhz-k+rt?tLIx78Ma+``RraYif_+axgC3@W!(wr*)UryS^T z1c6$(B4}j&yEETs#y5DlT3KOh=wzvV*?vd`4#X{E(8XA+Jgg(*>C=Mij6z5j>0jfj zFMjw&j#~)!L7|3AWqK0Z-{3(Nf<8@m#J<*MFV)C!2mu6

DtzY6 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 0 { + c.After(wait) + return anchor + } + if c.Shortcut(0, ui.KeyEscape) { + slog.Debug("mujica: tooltip dismiss") + st.dismissed = true + return anchor + } + tooltipShow(c, anchor.Bounds(), text) + return anchor +} + +// tooltipShow draws the tip below a, or above it when there is no room. +func tooltipShow(c *ui.Context, a ui.Rect, text string) { + k := Tokens(c) + u := Density(c).Unit() + size := theme.CaptionSize + 1 + tw, th := c.MeasureText(tooltipMaxWidth, ui.Span{Text: text, Size: size, Font: c.Theme().Font}) + padX, padY := u*2.5, u*1.5 + w, h := tw+2*(padX+theme.BorderWidth)+1, th+2*(padY+theme.BorderWidth) + x, y := overlayPlace(c, ui.Rect{X: a.X + a.W/2 - w/2, Y: a.Y, W: w, H: a.H}, w, h, 6) + ui.Overlay(c, func() { + ui.Box(c).Absolute().Left(x).Top(y).Width(w).Padding(padY, padX).Radius(theme.ControlRadius). + Background(k.Text).TextColor(k.Background).Border(theme.BorderWidth, k.Text). + PassThrough().Role(ui.RoleTooltip).Children(func() { + ui.Text(c, text).FontSize(size) + }) + }) +} diff --git a/tooltip_test.go b/tooltip_test.go new file mode 100644 index 0000000..190da23 --- /dev/null +++ b/tooltip_test.go @@ -0,0 +1,91 @@ +package mujica + +import ( + "testing" + "time" + + "github.com/egoist/mygo/ui" +) + +const tooltipTestDelay = 20 * time.Millisecond + +func tooltipTester(x, y float32) (*ui.Tester, *int) { + clicks := 0 + tt := ui.NewTester(func(c *ui.Context) { + Use(c, Settings{}) + ui.Column(c).Padding(y, 0, 0, x).Children(func() { + b := Button(c, "Share", ButtonOptions{}) + if b.Clicked() { + clicks++ + } + Tooltip(c, b, "Share with the court", TooltipOptions{Delay: tooltipTestDelay}) + }) + }, 400, 300) + return tt, &clicks +} + +func waitTooltip(tt *ui.Tester) { + time.Sleep(tooltipTestDelay + 10*time.Millisecond) + tt.Frame() +} + +func TestTooltipHoverDelay(t *testing.T) { + tt, clicks := tooltipTester(40, 40) + r, _ := tt.Find("Share") + tt.Move(r.X+4, r.Y+4) + if tt.HasText("Share with the court") { + t.Fatal("tip showed before the delay") + } + waitTooltip(tt) + tip, ok := tt.Find("Share with the court") + if !ok || tip.Y < r.Y+r.H { + t.Fatalf("tip %+v ok %v below %+v", tip, ok, r) + } + // The tip passes the pointer through: clicking it clicks what is below. + tt.Move(400, 300) + tt.Frame() + if tt.HasText("Share with the court") { + t.Fatal("tip stayed after leave") + } + _ = tt.Click("Share") + if *clicks != 1 { + t.Fatalf("clicks %d", *clicks) + } +} + +func TestTooltipFocusAndEscape(t *testing.T) { + tt, _ := tooltipTester(40, 40) + tt.Key(0, ui.KeyTab) + waitTooltip(tt) + if !tt.HasText("Share with the court") { + t.Fatal("no tip on keyboard focus") + } + tt.Key(0, ui.KeyEscape) + if tt.HasText("Share with the court") { + t.Fatal("Escape did not hide the tip") + } + waitTooltip(tt) + if tt.HasText("Share with the court") { + t.Fatal("tip came back while still focused") + } +} + +func TestTooltipEdgeFlips(t *testing.T) { + tt, _ := tooltipTester(330, 262) + r, _ := tt.Find("Share") + tt.Move(r.X+4, r.Y+4) + waitTooltip(tt) + tip, ok := tt.Find("Share with the court") + if !ok || tip.Y > r.Y || tip.X+tip.W > 400 { + t.Fatalf("tip %+v not above and inside for anchor %+v", tip, r) + } +} + +func TestTooltipSnapshot(t *testing.T) { + snapshot(t, "tooltip", 360, 140, func(c *ui.Context) { + ui.Column(c).Padding(24).AlignItems(ui.Start).Children(func() { + Button(c, "Seal", ButtonOptions{Variant: Secondary}) + tooltipShow(c, ui.Rect{X: 24, Y: 24, W: 62, H: 36}, "Seal the letter with wax") + }) + }) +}