Fix Android header menu anchoring
This commit is contained in:
@@ -5527,27 +5527,67 @@ func (u *ui) headerActions(gtx layout.Context) layout.Dimensions {
|
|||||||
if u.shouldShowDesktopWorkingHeader() {
|
if u.shouldShowDesktopWorkingHeader() {
|
||||||
return layout.Dimensions{}
|
return layout.Dimensions{}
|
||||||
}
|
}
|
||||||
|
spacing := gtx.Dp(unit.Dp(8))
|
||||||
|
rowOriginX := 0
|
||||||
|
var syncDims, lockDims, mainDims layout.Dimensions
|
||||||
row := func(gtx layout.Context) layout.Dimensions {
|
row := func(gtx layout.Context) layout.Dimensions {
|
||||||
return layout.Flex{Spacing: layout.SpaceStart}.Layout(gtx,
|
return layout.Flex{Spacing: layout.SpaceStart}.Layout(gtx,
|
||||||
layout.Rigid(u.syncButtonGroup),
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
syncDims = u.syncButtonGroup(gtx)
|
||||||
|
return syncDims
|
||||||
|
}),
|
||||||
layout.Rigid(layout.Spacer{Width: unit.Dp(8)}.Layout),
|
layout.Rigid(layout.Spacer{Width: unit.Dp(8)}.Layout),
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
btn := material.Button(u.theme, &u.lockVault, "Lock")
|
btn := material.Button(u.theme, &u.lockVault, "Lock")
|
||||||
return btn.Layout(gtx)
|
lockDims = btn.Layout(gtx)
|
||||||
|
return lockDims
|
||||||
}),
|
}),
|
||||||
layout.Rigid(layout.Spacer{Width: unit.Dp(8)}.Layout),
|
layout.Rigid(layout.Spacer{Width: unit.Dp(8)}.Layout),
|
||||||
layout.Rigid(u.mainMenuButtonGroup),
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
)
|
mainDims = u.mainMenuButtonGroup(gtx)
|
||||||
}
|
return mainDims
|
||||||
if u.mode == "phone" {
|
|
||||||
return layout.Flex{Alignment: layout.Middle}.Layout(gtx,
|
|
||||||
layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return layout.Dimensions{Size: gtx.Constraints.Min}
|
|
||||||
}),
|
}),
|
||||||
layout.Rigid(row),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return row(gtx)
|
|
||||||
|
rowOps := op.Record(gtx.Ops)
|
||||||
|
rowDims := row(gtx)
|
||||||
|
rowCall := rowOps.Stop()
|
||||||
|
|
||||||
|
if u.mode == "phone" {
|
||||||
|
rowOriginX = max(0, gtx.Constraints.Max.X-rowDims.Size.X)
|
||||||
|
}
|
||||||
|
|
||||||
|
drawMenu := func(menu layout.Widget, triggerRightX, triggerBottomY int) {
|
||||||
|
menuGTX := gtx
|
||||||
|
menuGTX.Constraints.Min = image.Point{}
|
||||||
|
menuGTX.Constraints.Max.X = gtx.Constraints.Max.X
|
||||||
|
menuOps := op.Record(gtx.Ops)
|
||||||
|
menuDims := layout.Inset{Top: unit.Dp(6)}.Layout(menuGTX, menu)
|
||||||
|
menuCall := menuOps.Stop()
|
||||||
|
menuX := anchoredMenuOriginX(gtx.Constraints.Max.X, rowOriginX, triggerRightX, menuDims.Size.X)
|
||||||
|
stack := op.Offset(image.Pt(menuX, triggerBottomY)).Push(gtx.Ops)
|
||||||
|
menuCall.Add(gtx.Ops)
|
||||||
|
stack.Pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
rowStack := op.Offset(image.Pt(rowOriginX, 0)).Push(gtx.Ops)
|
||||||
|
rowCall.Add(gtx.Ops)
|
||||||
|
rowStack.Pop()
|
||||||
|
|
||||||
|
if u.syncMenuOpen {
|
||||||
|
drawMenu(u.syncMenu, syncDims.Size.X, rowDims.Size.Y)
|
||||||
|
}
|
||||||
|
if u.mainMenuOpen {
|
||||||
|
triggerRightX := syncDims.Size.X + spacing + lockDims.Size.X + spacing + mainDims.Size.X
|
||||||
|
drawMenu(u.mainMenu, triggerRightX, rowDims.Size.Y)
|
||||||
|
}
|
||||||
|
|
||||||
|
width := rowDims.Size.X
|
||||||
|
if u.mode == "phone" {
|
||||||
|
width = gtx.Constraints.Max.X
|
||||||
|
}
|
||||||
|
return layout.Dimensions{Size: image.Pt(width, rowDims.Size.Y)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) mainMenu(gtx layout.Context) layout.Dimensions {
|
func (u *ui) mainMenu(gtx layout.Context) layout.Dimensions {
|
||||||
@@ -5670,22 +5710,7 @@ func (u *ui) syncButtonGroup(gtx layout.Context) layout.Dimensions {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
rowDims := row(gtx)
|
return row(gtx)
|
||||||
if !u.syncMenuOpen {
|
|
||||||
return rowDims
|
|
||||||
}
|
|
||||||
|
|
||||||
menuGTX := gtx
|
|
||||||
menuGTX.Constraints.Min = image.Point{}
|
|
||||||
menuOps := op.Record(gtx.Ops)
|
|
||||||
menuDims := layout.Inset{Top: unit.Dp(6)}.Layout(menuGTX, u.syncMenu)
|
|
||||||
menuCall := menuOps.Stop()
|
|
||||||
|
|
||||||
menuX := anchoredMenuX(rowDims.Size.X, menuDims.Size.X)
|
|
||||||
stack := op.Offset(image.Pt(menuX, rowDims.Size.Y)).Push(gtx.Ops)
|
|
||||||
menuCall.Add(gtx.Ops)
|
|
||||||
stack.Pop()
|
|
||||||
return rowDims
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) syncMenuToggle(gtx layout.Context) layout.Dimensions {
|
func (u *ui) syncMenuToggle(gtx layout.Context) layout.Dimensions {
|
||||||
@@ -7233,23 +7258,7 @@ func (u *ui) mainMenuButtonGroup(gtx layout.Context) layout.Dimensions {
|
|||||||
btn.Inset = layout.UniformInset(unit.Dp(8))
|
btn.Inset = layout.UniformInset(unit.Dp(8))
|
||||||
return btn.Layout(gtx)
|
return btn.Layout(gtx)
|
||||||
}
|
}
|
||||||
|
return button(gtx)
|
||||||
buttonDims := button(gtx)
|
|
||||||
if !u.mainMenuOpen {
|
|
||||||
return buttonDims
|
|
||||||
}
|
|
||||||
|
|
||||||
menuGTX := gtx
|
|
||||||
menuGTX.Constraints.Min = image.Point{}
|
|
||||||
menuOps := op.Record(gtx.Ops)
|
|
||||||
menuDims := layout.Inset{Top: unit.Dp(6)}.Layout(menuGTX, u.mainMenu)
|
|
||||||
menuCall := menuOps.Stop()
|
|
||||||
|
|
||||||
menuX := anchoredMenuX(buttonDims.Size.X, menuDims.Size.X)
|
|
||||||
stack := op.Offset(image.Pt(menuX, buttonDims.Size.Y)).Push(gtx.Ops)
|
|
||||||
menuCall.Add(gtx.Ops)
|
|
||||||
stack.Pop()
|
|
||||||
return buttonDims
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) syncMenuDropsBelowTrigger() bool {
|
func (u *ui) syncMenuDropsBelowTrigger() bool {
|
||||||
@@ -7272,6 +7281,17 @@ func anchoredMenuX(triggerWidth, menuWidth int) int {
|
|||||||
return triggerWidth - menuWidth
|
return triggerWidth - menuWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func anchoredMenuOriginX(containerWidth, rowOriginX, triggerRightX, menuWidth int) int {
|
||||||
|
x := rowOriginX + triggerRightX - menuWidth
|
||||||
|
if x < 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if x+menuWidth > containerWidth {
|
||||||
|
return max(0, containerWidth-menuWidth)
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
func detailLine(th *material.Theme, label, value string) layout.Widget {
|
func detailLine(th *material.Theme, label, value string) layout.Widget {
|
||||||
return func(gtx layout.Context) layout.Dimensions {
|
return func(gtx layout.Context) layout.Dimensions {
|
||||||
valueSize := unit.Sp(16)
|
valueSize := unit.Sp(16)
|
||||||
|
|||||||
@@ -367,6 +367,17 @@ func TestAnchoredMenuXAllowsWiderMenusToExtendLeft(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAnchoredMenuOriginXClampsToVisibleContainer(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
if got := anchoredMenuOriginX(360, 312, 360, 140); got != 220 {
|
||||||
|
t.Fatalf("anchoredMenuOriginX should keep a right-aligned menu visible, got %d want 220", got)
|
||||||
|
}
|
||||||
|
if got := anchoredMenuOriginX(360, 0, 44, 160); got != 0 {
|
||||||
|
t.Fatalf("anchoredMenuOriginX should clamp oversized left overflow to zero, got %d want 0", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestUICurrentVaultSummary(t *testing.T) {
|
func TestUICurrentVaultSummary(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user