Align header action cluster with layout.E
This commit is contained in:
+54
-13
@@ -9,6 +9,7 @@ import (
|
|||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
"gioui.org/widget"
|
"gioui.org/widget"
|
||||||
"gioui.org/widget/material"
|
"gioui.org/widget/material"
|
||||||
|
headerview "git.julianfamily.org/keepassgo/internal/appui/header"
|
||||||
headerlayout "git.julianfamily.org/keepassgo/internal/appui/header/layout"
|
headerlayout "git.julianfamily.org/keepassgo/internal/appui/header/layout"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -25,10 +26,10 @@ func (u *ui) header(gtx layout.Context) layout.Dimensions {
|
|||||||
}
|
}
|
||||||
return card(gtx, func(gtx layout.Context) layout.Dimensions {
|
return card(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||||
return layout.Flex{Alignment: layout.Middle}.Layout(gtx,
|
return layout.Flex{Alignment: layout.Middle}.Layout(gtx,
|
||||||
layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
return u.brandMark(gtx, 196, 56)
|
return u.brandMark(gtx, 196, 56)
|
||||||
}),
|
}),
|
||||||
layout.Rigid(u.headerActions),
|
layout.Flexed(1, u.headerActions),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -39,7 +40,7 @@ func (u *ui) headerActions(gtx layout.Context) layout.Dimensions {
|
|||||||
}
|
}
|
||||||
spacing := gtx.Dp(unit.Dp(8))
|
spacing := gtx.Dp(unit.Dp(8))
|
||||||
metrics := headerlayout.ActionMetrics{Spacing: spacing}
|
metrics := headerlayout.ActionMetrics{Spacing: spacing}
|
||||||
row := func(gtx layout.Context) layout.Dimensions {
|
actionCluster := func(gtx layout.Context) layout.Dimensions {
|
||||||
return layout.Flex{Spacing: layout.SpaceStart}.Layout(gtx,
|
return layout.Flex{Spacing: layout.SpaceStart}.Layout(gtx,
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
metrics.SyncDims = u.syncButtonGroup(gtx)
|
metrics.SyncDims = u.syncButtonGroup(gtx)
|
||||||
@@ -60,18 +61,16 @@ func (u *ui) headerActions(gtx layout.Context) layout.Dimensions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rowOps := op.Record(gtx.Ops)
|
rowOps := op.Record(gtx.Ops)
|
||||||
metrics.RowDims = row(gtx)
|
metrics.RowDims = actionCluster(gtx)
|
||||||
rowCall := rowOps.Stop()
|
rowCall := rowOps.Stop()
|
||||||
|
metrics.RowOriginX = max(0, gtx.Constraints.Max.X-metrics.RowDims.Size.X)
|
||||||
if u.usesCompactViewport() {
|
|
||||||
metrics.RowOriginX = max(0, gtx.Constraints.Max.X-metrics.RowDims.Size.X)
|
|
||||||
}
|
|
||||||
|
|
||||||
surface := headerlayout.DropdownSurface{ContainerWidth: gtx.Constraints.Max.X, LeftInset: 0, TopInset: 0}
|
surface := headerlayout.DropdownSurface{ContainerWidth: gtx.Constraints.Max.X, LeftInset: 0, TopInset: 0}
|
||||||
|
|
||||||
rowStack := op.Offset(image.Pt(metrics.RowOriginX, 0)).Push(gtx.Ops)
|
rowDims := layout.E.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||||
rowCall.Add(gtx.Ops)
|
rowCall.Add(gtx.Ops)
|
||||||
rowStack.Pop()
|
return metrics.RowDims
|
||||||
|
})
|
||||||
|
|
||||||
if u.usesCompactViewport() {
|
if u.usesCompactViewport() {
|
||||||
if u.syncMenuOpen {
|
if u.syncMenuOpen {
|
||||||
@@ -82,7 +81,7 @@ func (u *ui) headerActions(gtx layout.Context) layout.Dimensions {
|
|||||||
u.phoneMainMenuVisible = true
|
u.phoneMainMenuVisible = true
|
||||||
u.phoneMainMenuAnchor = metrics.MainAnchor().Point()
|
u.phoneMainMenuAnchor = metrics.MainAnchor().Point()
|
||||||
}
|
}
|
||||||
return layout.Dimensions{Size: image.Pt(gtx.Constraints.Max.X, metrics.RowDims.Size.Y)}
|
return layout.Dimensions{Size: image.Pt(gtx.Constraints.Max.X, rowDims.Size.Y)}
|
||||||
}
|
}
|
||||||
|
|
||||||
if u.syncMenuOpen {
|
if u.syncMenuOpen {
|
||||||
@@ -92,7 +91,7 @@ func (u *ui) headerActions(gtx layout.Context) layout.Dimensions {
|
|||||||
surface.Draw(gtx, metrics.MainAnchor(), u.mainMenu)
|
surface.Draw(gtx, metrics.MainAnchor(), u.mainMenu)
|
||||||
}
|
}
|
||||||
|
|
||||||
return layout.Dimensions{Size: image.Pt(metrics.RowDims.Size.X, metrics.RowDims.Size.Y)}
|
return rowDims
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) topRightActionOrder() []string {
|
func (u *ui) topRightActionOrder() []string {
|
||||||
@@ -174,3 +173,45 @@ func (u *ui) brandImage(gtx layout.Context, src paint.ImageOp, widthDP, heightDP
|
|||||||
gtx.Constraints.Max = image.Pt(width, height)
|
gtx.Constraints.Max = image.Pt(width, height)
|
||||||
return img.Layout(gtx)
|
return img.Layout(gtx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *ui) mainMenu(gtx layout.Context) layout.Dimensions {
|
||||||
|
rows := []layout.Widget{
|
||||||
|
func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return tonedButton(gtx, u.theme, &u.showEntries, "Entries")
|
||||||
|
},
|
||||||
|
func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return tonedButton(gtx, u.theme, &u.showRecycle, "Recycle Bin")
|
||||||
|
},
|
||||||
|
func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return tonedButton(gtx, u.theme, &u.showAPITokens, "API Tokens")
|
||||||
|
},
|
||||||
|
func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return tonedButton(gtx, u.theme, &u.showAPIAudit, "API Audit")
|
||||||
|
},
|
||||||
|
func(gtx layout.Context) layout.Dimensions { return tonedButton(gtx, u.theme, &u.showAbout, "About") },
|
||||||
|
func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return tonedButton(gtx, u.theme, &u.openSecuritySettings, "Settings")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return headerview.MainMenu(gtx, u.theme, rows, compactCard)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *ui) mainMenuButtonGroup(gtx layout.Context) layout.Dimensions {
|
||||||
|
icon := u.menuIcon
|
||||||
|
if icon == nil {
|
||||||
|
icon = u.settingsIcon
|
||||||
|
}
|
||||||
|
return headerview.MainMenuButtonGroup(gtx, u.theme, &u.toggleMainMenu, icon, u.mainMenuOpen, selectedColor, accentColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func intrinsicCompactCard(gtx layout.Context, w layout.Widget) layout.Dimensions {
|
||||||
|
return headerlayout.IntrinsicCompactCard(gtx, w, compactCard)
|
||||||
|
}
|
||||||
|
|
||||||
|
func menuActionWidth(gtx layout.Context, rows []layout.Widget) int {
|
||||||
|
return headerlayout.MenuActionWidth(gtx, rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
func rightAlignedMenuAction(gtx layout.Context, width int, child layout.Widget) layout.Dimensions {
|
||||||
|
return headerlayout.RightAlignedAction(gtx, width, child)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package appui
|
package layout
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func intrinsicCompactCard(gtx layout.Context, w layout.Widget) layout.Dimensions {
|
func IntrinsicCompactCard(gtx layout.Context, w layout.Widget, card func(layout.Context, layout.Widget) layout.Dimensions) layout.Dimensions {
|
||||||
measureGTX := gtx
|
measureGTX := gtx
|
||||||
measureGTX.Constraints.Min = image.Point{}
|
measureGTX.Constraints.Min = image.Point{}
|
||||||
measureGTX.Constraints.Max.X = gtx.Constraints.Max.X
|
measureGTX.Constraints.Max.X = gtx.Constraints.Max.X
|
||||||
@@ -24,10 +24,10 @@ func intrinsicCompactCard(gtx layout.Context, w layout.Widget) layout.Dimensions
|
|||||||
gtx.Constraints.Min.X = width
|
gtx.Constraints.Min.X = width
|
||||||
gtx.Constraints.Max.X = width
|
gtx.Constraints.Max.X = width
|
||||||
}
|
}
|
||||||
return compactCard(gtx, w)
|
return card(gtx, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func menuActionWidth(gtx layout.Context, rows []layout.Widget) int {
|
func MenuActionWidth(gtx layout.Context, rows []layout.Widget) int {
|
||||||
width := 0
|
width := 0
|
||||||
for _, row := range rows {
|
for _, row := range rows {
|
||||||
measureGTX := gtx
|
measureGTX := gtx
|
||||||
@@ -42,7 +42,7 @@ func menuActionWidth(gtx layout.Context, rows []layout.Widget) int {
|
|||||||
return width
|
return width
|
||||||
}
|
}
|
||||||
|
|
||||||
func rightAlignedMenuAction(gtx layout.Context, width int, child layout.Widget) layout.Dimensions {
|
func RightAlignedAction(gtx layout.Context, width int, child layout.Widget) layout.Dimensions {
|
||||||
if width <= 0 {
|
if width <= 0 {
|
||||||
return child(gtx)
|
return child(gtx)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package header
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
|
||||||
|
"gioui.org/layout"
|
||||||
|
"gioui.org/unit"
|
||||||
|
"gioui.org/widget"
|
||||||
|
"gioui.org/widget/material"
|
||||||
|
headerlayout "git.julianfamily.org/keepassgo/internal/appui/header/layout"
|
||||||
|
)
|
||||||
|
|
||||||
|
func MainMenu(gtx layout.Context, theme *material.Theme, rows []layout.Widget, card func(layout.Context, layout.Widget) layout.Dimensions) layout.Dimensions {
|
||||||
|
rowWidth := headerlayout.MenuActionWidth(gtx, rows)
|
||||||
|
return headerlayout.IntrinsicCompactCard(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||||
|
children := make([]layout.FlexChild, 0, (len(rows)*2)-1)
|
||||||
|
for i, row := range rows {
|
||||||
|
if i > 0 {
|
||||||
|
children = append(children, layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout))
|
||||||
|
}
|
||||||
|
current := row
|
||||||
|
children = append(children, layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return headerlayout.RightAlignedAction(gtx, rowWidth, current)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, children...)
|
||||||
|
}, card)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MainMenuButtonGroup(gtx layout.Context, theme *material.Theme, click *widget.Clickable, icon *widget.Icon, open bool, selectedColor, accentColor color.NRGBA) layout.Dimensions {
|
||||||
|
btn := material.IconButton(theme, click, icon, "Menu")
|
||||||
|
if open {
|
||||||
|
btn.Background = accentColor
|
||||||
|
btn.Color = color.NRGBA{R: 255, G: 252, B: 247, A: 255}
|
||||||
|
} else {
|
||||||
|
btn.Background = selectedColor
|
||||||
|
btn.Color = accentColor
|
||||||
|
}
|
||||||
|
btn.Size = unit.Dp(18)
|
||||||
|
btn.Inset = layout.UniformInset(unit.Dp(8))
|
||||||
|
return btn.Layout(gtx)
|
||||||
|
}
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
package appui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"image/color"
|
|
||||||
|
|
||||||
"gioui.org/layout"
|
|
||||||
"gioui.org/unit"
|
|
||||||
"gioui.org/widget/material"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (u *ui) mainMenu(gtx layout.Context) layout.Dimensions {
|
|
||||||
rows := []layout.Widget{
|
|
||||||
func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return tonedButton(gtx, u.theme, &u.showEntries, "Entries")
|
|
||||||
},
|
|
||||||
func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return tonedButton(gtx, u.theme, &u.showRecycle, "Recycle Bin")
|
|
||||||
},
|
|
||||||
func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return tonedButton(gtx, u.theme, &u.showAPITokens, "API Tokens")
|
|
||||||
},
|
|
||||||
func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return tonedButton(gtx, u.theme, &u.showAPIAudit, "API Audit")
|
|
||||||
},
|
|
||||||
func(gtx layout.Context) layout.Dimensions { return tonedButton(gtx, u.theme, &u.showAbout, "About") },
|
|
||||||
func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return tonedButton(gtx, u.theme, &u.openSecuritySettings, "Settings")
|
|
||||||
},
|
|
||||||
}
|
|
||||||
rowWidth := menuActionWidth(gtx, rows)
|
|
||||||
return intrinsicCompactCard(gtx, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return rightAlignedMenuAction(gtx, rowWidth, rows[0]) }),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return rightAlignedMenuAction(gtx, rowWidth, rows[1]) }),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return rightAlignedMenuAction(gtx, rowWidth, rows[2]) }),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return rightAlignedMenuAction(gtx, rowWidth, rows[3]) }),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return rightAlignedMenuAction(gtx, rowWidth, rows[4]) }),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return rightAlignedMenuAction(gtx, rowWidth, rows[5]) }),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *ui) mainMenuButtonGroup(gtx layout.Context) layout.Dimensions {
|
|
||||||
icon := u.menuIcon
|
|
||||||
if icon == nil {
|
|
||||||
icon = u.settingsIcon
|
|
||||||
}
|
|
||||||
btn := material.IconButton(u.theme, &u.toggleMainMenu, icon, "Menu")
|
|
||||||
if u.mainMenuOpen {
|
|
||||||
btn.Background = accentColor
|
|
||||||
btn.Color = color.NRGBA{R: 255, G: 252, B: 247, A: 255}
|
|
||||||
} else {
|
|
||||||
btn.Background = selectedColor
|
|
||||||
btn.Color = accentColor
|
|
||||||
}
|
|
||||||
btn.Size = unit.Dp(18)
|
|
||||||
btn.Inset = layout.UniformInset(unit.Dp(8))
|
|
||||||
return btn.Layout(gtx)
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user