all: [API] replace unit.Value with separate unit.Dp, unit.Sp types

The unit.Value is a struct and thus more inconvenient to use than its
underlying float32 type. In addition, most uses don't need a general
value, but rather a specific unit given by the context. This change
replaces unit.Value with two float32 units, Dp and Sp. It also changes
variables and parameters of unit.Value to a specific unit type matching
the context. That is, unit.Dp everywhere except for text sizes which are
in Sp.

Switching to typed float32s has multiple advantages

- They can be constants:

const touchSlop = unit.Dp(16)

- Casting untyped constants is no longer necessary:

insets := layout.UniformInset(16)

- Calculation with values is natural:

func (s ScrollbarStyle) Width() unit.Dp {
	return s.Indicator.MinorWidth + s.Track.MinorPadding + s.Track.MinorPadding
}

The main API change is that calls to gtx.Px must be replaced with either
gtx.Dp or gtx.Sp depending on the unit.

Idea by Christophe Meessen.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2022-04-25 10:08:01 +02:00
parent 48a8540a68
commit 3d37491342
35 changed files with 212 additions and 307 deletions
+4 -4
View File
@@ -15,16 +15,16 @@ import (
// Border lays out a widget and draws a border inside it.
type Border struct {
Color color.NRGBA
CornerRadius unit.Value
Width unit.Value
CornerRadius unit.Dp
Width unit.Dp
}
func (b Border) Layout(gtx layout.Context, w layout.Widget) layout.Dimensions {
dims := w(gtx)
sz := dims.Size
rr := gtx.Px(b.CornerRadius)
width := gtx.Px(b.Width)
rr := gtx.Dp(b.CornerRadius)
width := gtx.Dp(b.Width)
sz.X -= width
sz.Y -= width
+1 -2
View File
@@ -10,7 +10,6 @@ import (
"gioui.org/io/system"
"gioui.org/layout"
"gioui.org/op/clip"
"gioui.org/unit"
)
// Decorations handles the states of window decorations.
@@ -67,7 +66,7 @@ func (d *Decorations) Clickable(action system.Action) *Clickable {
// LayoutResize lays out the resize actions.
func (d *Decorations) LayoutResize(gtx layout.Context, actions system.Action) {
cs := gtx.Constraints.Max
wh := gtx.Px(unit.Dp(10))
wh := gtx.Dp(10)
s := []struct {
system.Action
image.Rectangle
+3 -3
View File
@@ -497,12 +497,12 @@ func (e *Editor) calculateViewSize(gtx layout.Context) image.Point {
}
// Layout lays out the editor. If content is not nil, it is laid out on top.
func (e *Editor) Layout(gtx layout.Context, sh text.Shaper, font text.Font, size unit.Value, content layout.Widget) layout.Dimensions {
func (e *Editor) Layout(gtx layout.Context, sh text.Shaper, font text.Font, size unit.Sp, content layout.Widget) layout.Dimensions {
if e.locale != gtx.Locale {
e.locale = gtx.Locale
e.invalidate()
}
textSize := fixed.I(gtx.Px(size))
textSize := fixed.I(gtx.Sp(size))
if e.font != font || e.textSize != textSize {
e.invalidate()
e.font = font
@@ -776,7 +776,7 @@ func (e *Editor) PaintText(gtx layout.Context) {
// caretWidth returns the width occupied by the caret for the current
// gtx.
func (e *Editor) caretWidth(gtx layout.Context) int {
carWidth2 := gtx.Px(unit.Dp(1)) / 2
carWidth2 := gtx.Dp(1) / 2
if carWidth2 < 1 {
carWidth2 = 1
}
+12 -12
View File
@@ -47,7 +47,7 @@ func TestEditorZeroDimensions(t *testing.T) {
Locale: english,
}
cache := text.NewCache(gofont.Collection())
fontSize := unit.Px(10)
fontSize := unit.Sp(10)
font := text.Font{}
e := new(Editor)
dims := e.Layout(gtx, cache, font, fontSize, nil)
@@ -63,7 +63,7 @@ func TestEditorConfigurations(t *testing.T) {
Locale: english,
}
cache := text.NewCache(gofont.Collection())
fontSize := unit.Px(10)
fontSize := unit.Sp(10)
font := text.Font{}
sentence := "\n\n\n\n\n\n\n\n\n\n\n\nthe quick brown fox jumps over the lazy dog"
runes := len([]rune(sentence))
@@ -103,7 +103,7 @@ func TestEditor(t *testing.T) {
Locale: english,
}
cache := text.NewCache(gofont.Collection())
fontSize := unit.Px(10)
fontSize := unit.Sp(10)
font := text.Font{}
// Regression test for bad in-cluster rune offset math.
@@ -206,7 +206,7 @@ func TestEditorRTL(t *testing.T) {
Locale: arabic,
}
cache := text.NewCache(arabicCollection)
fontSize := unit.Px(10)
fontSize := unit.Sp(10)
font := text.Font{}
e.SetCaret(0, 0) // shouldn't panic
@@ -282,7 +282,7 @@ func TestEditorLigature(t *testing.T) {
Face: face,
},
})
fontSize := unit.Px(10)
fontSize := unit.Sp(10)
font := text.Font{}
/*
@@ -399,7 +399,7 @@ func TestEditorDimensions(t *testing.T) {
Locale: english,
}
cache := text.NewCache(gofont.Collection())
fontSize := unit.Px(10)
fontSize := unit.Sp(10)
font := text.Font{}
dims := e.Layout(gtx, cache, font, fontSize, nil)
if dims.Size.X == 0 {
@@ -446,7 +446,7 @@ func TestEditorCaretConsistency(t *testing.T) {
Locale: english,
}
cache := text.NewCache(gofont.Collection())
fontSize := unit.Px(10)
fontSize := unit.Sp(10)
font := text.Font{}
for _, a := range []text.Alignment{text.Start, text.Middle, text.End} {
e := &Editor{
@@ -539,7 +539,7 @@ func TestEditorMoveWord(t *testing.T) {
Locale: english,
}
cache := text.NewCache(gofont.Collection())
fontSize := unit.Px(10)
fontSize := unit.Sp(10)
font := text.Font{}
e.SetText(t)
e.Layout(gtx, cache, font, fontSize, nil)
@@ -644,7 +644,7 @@ func TestEditorInsert(t *testing.T) {
Locale: english,
}
cache := text.NewCache(gofont.Collection())
fontSize := unit.Px(10)
fontSize := unit.Sp(10)
font := text.Font{}
e.SetText(t)
e.Layout(gtx, cache, font, fontSize, nil)
@@ -734,7 +734,7 @@ func TestEditorDeleteWord(t *testing.T) {
Locale: english,
}
cache := text.NewCache(gofont.Collection())
fontSize := unit.Px(10)
fontSize := unit.Sp(10)
font := text.Font{}
e.SetText(t)
e.Layout(gtx, cache, font, fontSize, nil)
@@ -789,7 +789,7 @@ g 2 4 6 8 g
}
cache := text.NewCache(gofont.Collection())
font := text.Font{}
fontSize := unit.Px(10)
fontSize := unit.Sp(10)
selected := func(start, end int) string {
// Layout once with no events; populate e.lines.
@@ -879,7 +879,7 @@ func TestSelectMove(t *testing.T) {
}
cache := text.NewCache(gofont.Collection())
font := text.Font{}
fontSize := unit.Px(10)
fontSize := unit.Sp(10)
// Layout once to populate e.lines and get focus.
gtx.Queue = newQueue(key.FocusEvent{Focus: true})
+2 -2
View File
@@ -24,7 +24,7 @@ type Icon struct {
imgColor color.NRGBA
}
var defaultIconSize = unit.Dp(24)
const defaultIconSize = unit.Dp(24)
// NewIcon returns a new Icon from IconVG data.
func NewIcon(data []byte) (*Icon, error) {
@@ -39,7 +39,7 @@ func NewIcon(data []byte) (*Icon, error) {
func (ic *Icon) Layout(gtx layout.Context, color color.NRGBA) layout.Dimensions {
sz := gtx.Constraints.Min.X
if sz == 0 {
sz = gtx.Metric.Px(defaultIconSize)
sz = gtx.Dp(defaultIconSize)
}
size := gtx.Constraints.Constrain(image.Pt(sz, sz))
defer clip.Rect{Max: size}.Push(gtx.Ops).Pop()
+1 -1
View File
@@ -39,7 +39,7 @@ func (im Image) Layout(gtx layout.Context) layout.Dimensions {
size := im.Src.Size()
wf, hf := float32(size.X), float32(size.Y)
w, h := gtx.Px(unit.Dp(wf*scale)), gtx.Px(unit.Dp(hf*scale))
w, h := gtx.Dp(unit.Dp(wf*scale)), gtx.Dp(unit.Dp(hf*scale))
dims, trans := im.Fit.scale(gtx.Constraints, im.Position, layout.Dimensions{Size: image.Pt(w, h)})
defer clip.Rect{Max: dims.Size}.Push(gtx.Ops).Pop()
+2 -2
View File
@@ -96,9 +96,9 @@ func (p1 screenPos) Less(p2 screenPos) bool {
return p1.Y < p2.Y || (p1.Y == p2.Y && p1.X < p2.X)
}
func (l Label) Layout(gtx layout.Context, s text.Shaper, font text.Font, size unit.Value, txt string) layout.Dimensions {
func (l Label) Layout(gtx layout.Context, s text.Shaper, font text.Font, size unit.Sp, txt string) layout.Dimensions {
cs := gtx.Constraints
textSize := fixed.I(gtx.Px(size))
textSize := fixed.I(gtx.Sp(size))
lines := s.LayoutString(font, textSize, cs.Max.X, gtx.Locale, txt)
if max := l.MaxLines; max > 0 && len(lines) > max {
lines = lines[:max]
+13 -13
View File
@@ -23,9 +23,9 @@ type ButtonStyle struct {
// Color is the text color.
Color color.NRGBA
Font text.Font
TextSize unit.Value
TextSize unit.Sp
Background color.NRGBA
CornerRadius unit.Value
CornerRadius unit.Dp
Inset layout.Inset
Button *widget.Clickable
shaper text.Shaper
@@ -33,7 +33,7 @@ type ButtonStyle struct {
type ButtonLayoutStyle struct {
Background color.NRGBA
CornerRadius unit.Value
CornerRadius unit.Dp
Button *widget.Clickable
}
@@ -43,7 +43,7 @@ type IconButtonStyle struct {
Color color.NRGBA
Icon *widget.Icon
// Size is the icon size.
Size unit.Value
Size unit.Dp
Inset layout.Inset
Button *widget.Clickable
Description string
@@ -53,12 +53,12 @@ func Button(th *Theme, button *widget.Clickable, txt string) ButtonStyle {
return ButtonStyle{
Text: txt,
Color: th.Palette.ContrastFg,
CornerRadius: unit.Dp(4),
CornerRadius: 4,
Background: th.Palette.ContrastBg,
TextSize: th.TextSize.Scale(14.0 / 16.0),
TextSize: th.TextSize * 14.0 / 16.0,
Inset: layout.Inset{
Top: unit.Dp(10), Bottom: unit.Dp(10),
Left: unit.Dp(12), Right: unit.Dp(12),
Top: 10, Bottom: 10,
Left: 12, Right: 12,
},
Button: button,
shaper: th.Shaper,
@@ -69,7 +69,7 @@ func ButtonLayout(th *Theme, button *widget.Clickable) ButtonLayoutStyle {
return ButtonLayoutStyle{
Button: button,
Background: th.Palette.ContrastBg,
CornerRadius: unit.Dp(4),
CornerRadius: 4,
}
}
@@ -78,8 +78,8 @@ func IconButton(th *Theme, button *widget.Clickable, icon *widget.Icon, descript
Background: th.Palette.ContrastBg,
Color: th.Palette.ContrastFg,
Icon: icon,
Size: unit.Dp(24),
Inset: layout.UniformInset(unit.Dp(12)),
Size: 24,
Inset: layout.UniformInset(12),
Button: button,
Description: description,
}
@@ -129,7 +129,7 @@ func (b ButtonLayoutStyle) Layout(gtx layout.Context, w layout.Widget) layout.Di
semantic.Button.Add(gtx.Ops)
return layout.Stack{Alignment: layout.Center}.Layout(gtx,
layout.Expanded(func(gtx layout.Context) layout.Dimensions {
rr := gtx.Px(b.CornerRadius)
rr := gtx.Dp(b.CornerRadius)
defer clip.UniformRRect(image.Rectangle{Max: gtx.Constraints.Min}, rr).Push(gtx.Ops).Pop()
background := b.Background
switch {
@@ -178,7 +178,7 @@ func (b IconButtonStyle) Layout(gtx layout.Context) layout.Dimensions {
}),
layout.Stacked(func(gtx layout.Context) layout.Dimensions {
return b.Inset.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
size := gtx.Px(b.Size)
size := gtx.Dp(b.Size)
if b.Icon != nil {
gtx.Constraints.Min = image.Point{X: size}
b.Icon.Layout(gtx, b.Color)
+6 -6
View File
@@ -19,9 +19,9 @@ type checkable struct {
Label string
Color color.NRGBA
Font text.Font
TextSize unit.Value
TextSize unit.Sp
IconColor color.NRGBA
Size unit.Value
Size unit.Dp
shaper text.Shaper
checkedStateIcon *widget.Icon
uncheckedStateIcon *widget.Icon
@@ -39,7 +39,7 @@ func (c *checkable) layout(gtx layout.Context, checked, hovered bool) layout.Dim
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return layout.Stack{Alignment: layout.Center}.Layout(gtx,
layout.Stacked(func(gtx layout.Context) layout.Dimensions {
size := gtx.Px(c.Size) * 4 / 3
size := gtx.Dp(c.Size) * 4 / 3
dims := layout.Dimensions{
Size: image.Point{X: size, Y: size},
}
@@ -55,8 +55,8 @@ func (c *checkable) layout(gtx layout.Context, checked, hovered bool) layout.Dim
return dims
}),
layout.Stacked(func(gtx layout.Context) layout.Dimensions {
return layout.UniformInset(unit.Dp(2)).Layout(gtx, func(gtx layout.Context) layout.Dimensions {
size := gtx.Px(c.Size)
return layout.UniformInset(2).Layout(gtx, func(gtx layout.Context) layout.Dimensions {
size := gtx.Dp(c.Size)
col := c.IconColor
if gtx.Queue == nil {
col = f32color.Disabled(col)
@@ -72,7 +72,7 @@ func (c *checkable) layout(gtx layout.Context, checked, hovered bool) layout.Dim
}),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return layout.UniformInset(unit.Dp(2)).Layout(gtx, func(gtx layout.Context) layout.Dimensions {
return layout.UniformInset(2).Layout(gtx, func(gtx layout.Context) layout.Dimensions {
paint.ColorOp{Color: c.Color}.Add(gtx.Ops)
return widget.Label{}.Layout(gtx, c.shaper, c.Font, c.TextSize, c.Label)
})
+2 -3
View File
@@ -5,7 +5,6 @@ package material
import (
"gioui.org/io/semantic"
"gioui.org/layout"
"gioui.org/unit"
"gioui.org/widget"
)
@@ -21,8 +20,8 @@ func CheckBox(th *Theme, checkBox *widget.Bool, label string) CheckBoxStyle {
Label: label,
Color: th.Palette.Fg,
IconColor: th.Palette.ContrastBg,
TextSize: th.TextSize.Scale(14.0 / 16.0),
Size: unit.Dp(26),
TextSize: th.TextSize * 14.0 / 16.0,
Size: 26,
shaper: th.Shaper,
checkedStateIcon: th.Icon.CheckBoxChecked,
uncheckedStateIcon: th.Icon.CheckBoxUnchecked,
+14 -14
View File
@@ -53,7 +53,7 @@ func (d *DecorationsStyle) Layout(gtx layout.Context) layout.Dimensions {
func (d *DecorationsStyle) layoutDecorations(gtx layout.Context) layout.Dimensions {
gtx.Constraints.Min.Y = 0
inset := layout.UniformInset(unit.Dp(10))
inset := layout.UniformInset(10)
return layout.Flex{
Axis: layout.Horizontal,
Alignment: layout.Middle,
@@ -116,7 +116,7 @@ func (d *DecorationsStyle) layoutDecorations(gtx layout.Context) layout.Dimensio
)
}
var (
const (
winIconSize = unit.Dp(20)
winIconMargin = unit.Dp(4)
winIconStroke = unit.Dp(2)
@@ -124,10 +124,10 @@ var (
// minimizeWindows draws a line icon representing the minimize action.
func minimizeWindow(gtx layout.Context) layout.Dimensions {
size := gtx.Px(winIconSize)
size := gtx.Dp(winIconSize)
size32 := float32(size)
margin := float32(gtx.Px(winIconMargin))
width := float32(gtx.Px(winIconStroke))
margin := float32(gtx.Dp(winIconMargin))
width := float32(gtx.Dp(winIconStroke))
var p clip.Path
p.Begin(gtx.Ops)
p.MoveTo(f32.Point{X: margin, Y: size32 - margin})
@@ -143,9 +143,9 @@ func minimizeWindow(gtx layout.Context) layout.Dimensions {
// maximizeWindow draws a rectangle representing the maximize action.
func maximizeWindow(gtx layout.Context) layout.Dimensions {
size := gtx.Px(winIconSize)
margin := gtx.Px(winIconMargin)
width := gtx.Px(winIconStroke)
size := gtx.Dp(winIconSize)
margin := gtx.Dp(winIconMargin)
width := gtx.Dp(winIconStroke)
r := clip.RRect{
Rect: image.Rect(margin, margin, size-margin, size-margin),
}
@@ -166,9 +166,9 @@ func maximizeWindow(gtx layout.Context) layout.Dimensions {
// maximizedWindow draws interleaved rectangles representing the un-maximize action.
func maximizedWindow(gtx layout.Context) layout.Dimensions {
size := gtx.Px(winIconSize)
margin := gtx.Px(winIconMargin)
width := gtx.Px(winIconStroke)
size := gtx.Dp(winIconSize)
margin := gtx.Dp(winIconMargin)
width := gtx.Dp(winIconStroke)
r := clip.RRect{
Rect: image.Rect(margin, margin, size-2*margin, size-2*margin),
}
@@ -192,10 +192,10 @@ func maximizedWindow(gtx layout.Context) layout.Dimensions {
// closeWindow draws a cross representing the close action.
func closeWindow(gtx layout.Context) layout.Dimensions {
size := gtx.Px(winIconSize)
size := gtx.Dp(winIconSize)
size32 := float32(size)
margin := float32(gtx.Px(winIconMargin))
width := float32(gtx.Px(winIconStroke))
margin := float32(gtx.Dp(winIconMargin))
width := float32(gtx.Dp(winIconStroke))
var p clip.Path
p.Begin(gtx.Ops)
p.MoveTo(f32.Point{X: margin, Y: margin})
+1 -1
View File
@@ -17,7 +17,7 @@ import (
type EditorStyle struct {
Font text.Font
TextSize unit.Value
TextSize unit.Sp
// Color is the text color.
Color color.NRGBA
// Hint contains the text displayed when the editor is empty.
+13 -13
View File
@@ -22,47 +22,47 @@ type LabelStyle struct {
// MaxLines limits the number of lines. Zero means no limit.
MaxLines int
Text string
TextSize unit.Value
TextSize unit.Sp
shaper text.Shaper
}
func H1(th *Theme, txt string) LabelStyle {
label := Label(th, th.TextSize.Scale(96.0/16.0), txt)
label := Label(th, th.TextSize*96.0/16.0, txt)
label.Font.Weight = text.Light
return label
}
func H2(th *Theme, txt string) LabelStyle {
label := Label(th, th.TextSize.Scale(60.0/16.0), txt)
label := Label(th, th.TextSize*60.0/16.0, txt)
label.Font.Weight = text.Light
return label
}
func H3(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize.Scale(48.0/16.0), txt)
return Label(th, th.TextSize*48.0/16.0, txt)
}
func H4(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize.Scale(34.0/16.0), txt)
return Label(th, th.TextSize*34.0/16.0, txt)
}
func H5(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize.Scale(24.0/16.0), txt)
return Label(th, th.TextSize*24.0/16.0, txt)
}
func H6(th *Theme, txt string) LabelStyle {
label := Label(th, th.TextSize.Scale(20.0/16.0), txt)
label := Label(th, th.TextSize*20.0/16.0, txt)
label.Font.Weight = text.Medium
return label
}
func Subtitle1(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize.Scale(16.0/16.0), txt)
return Label(th, th.TextSize*16.0/16.0, txt)
}
func Subtitle2(th *Theme, txt string) LabelStyle {
label := Label(th, th.TextSize.Scale(14.0/16.0), txt)
label := Label(th, th.TextSize*14.0/16.0, txt)
label.Font.Weight = text.Medium
return label
}
@@ -72,18 +72,18 @@ func Body1(th *Theme, txt string) LabelStyle {
}
func Body2(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize.Scale(14.0/16.0), txt)
return Label(th, th.TextSize*14.0/16.0, txt)
}
func Caption(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize.Scale(12.0/16.0), txt)
return Label(th, th.TextSize*12.0/16.0, txt)
}
func Overline(th *Theme, txt string) LabelStyle {
return Label(th, th.TextSize.Scale(10.0/16.0), txt)
return Label(th, th.TextSize*10.0/16.0, txt)
}
func Label(th *Theme, size unit.Value, txt string) LabelStyle {
func Label(th *Theme, size unit.Sp, txt string) LabelStyle {
return LabelStyle{
Text: txt,
Color: th.Palette.Fg,
+16 -16
View File
@@ -50,7 +50,7 @@ type ScrollTrackStyle struct {
// MajorPadding and MinorPadding along the major and minor axis of the
// scrollbar's track. This is used to keep the scrollbar from touching
// the edges of the content area.
MajorPadding, MinorPadding unit.Value
MajorPadding, MinorPadding unit.Dp
// Color of the track background.
Color color.NRGBA
}
@@ -59,16 +59,16 @@ type ScrollTrackStyle struct {
type ScrollIndicatorStyle struct {
// MajorMinLen is the smallest that the scroll indicator is allowed to
// be along the major axis.
MajorMinLen unit.Value
MajorMinLen unit.Dp
// MinorWidth is the width of the scroll indicator across the minor axis.
MinorWidth unit.Value
MinorWidth unit.Dp
// Color and HoverColor are the normal and hovered colors of the scroll
// indicator.
Color, HoverColor color.NRGBA
// CornerRadius is the corner radius of the rectangular indicator. 0
// will produce square corners. 0.5*MinorWidth will produce perfectly
// round corners.
CornerRadius unit.Value
CornerRadius unit.Dp
}
// ScrollbarStyle configures the presentation of a scrollbar.
@@ -89,13 +89,13 @@ func Scrollbar(th *Theme, state *widget.Scrollbar) ScrollbarStyle {
return ScrollbarStyle{
Scrollbar: state,
Track: ScrollTrackStyle{
MajorPadding: unit.Dp(2),
MinorPadding: unit.Dp(2),
MajorPadding: 2,
MinorPadding: 2,
},
Indicator: ScrollIndicatorStyle{
MajorMinLen: unit.Dp(8),
MinorWidth: unit.Dp(6),
CornerRadius: unit.Dp(3),
MajorMinLen: 8,
MinorWidth: 6,
CornerRadius: 3,
Color: lightFg,
HoverColor: darkFg,
},
@@ -104,8 +104,8 @@ func Scrollbar(th *Theme, state *widget.Scrollbar) ScrollbarStyle {
// Width returns the minor axis width of the scrollbar in its current
// configuration (taking padding for the scroll track into account).
func (s ScrollbarStyle) Width(metric unit.Metric) unit.Value {
return unit.Add(metric, s.Indicator.MinorWidth, s.Track.MinorPadding, s.Track.MinorPadding)
func (s ScrollbarStyle) Width() unit.Dp {
return s.Indicator.MinorWidth + s.Track.MinorPadding + s.Track.MinorPadding
}
// Layout the scrollbar.
@@ -119,7 +119,7 @@ func (s ScrollbarStyle) Layout(gtx layout.Context, axis layout.Axis, viewportSta
convert := axis.Convert
maxMajorAxis := convert(gtx.Constraints.Max).X
gtx.Constraints.Min.X = maxMajorAxis
gtx.Constraints.Min.Y = gtx.Px(s.Width(gtx.Metric))
gtx.Constraints.Min.Y = gtx.Dp(s.Width())
gtx.Constraints.Min = convert(gtx.Constraints.Min)
gtx.Constraints.Max = gtx.Constraints.Min
@@ -179,15 +179,15 @@ func (s ScrollbarStyle) layout(gtx layout.Context, axis layout.Axis, viewportSta
trackLen := gtx.Constraints.Min.X
viewStart := int(math.Round(float64(viewportStart) * float64(trackLen)))
viewEnd := int(math.Round(float64(viewportEnd) * float64(trackLen)))
indicatorLen := max(viewEnd-viewStart, gtx.Px(s.Indicator.MajorMinLen))
indicatorLen := max(viewEnd-viewStart, gtx.Dp(s.Indicator.MajorMinLen))
if viewStart+indicatorLen > trackLen {
viewStart = trackLen - indicatorLen
}
indicatorDims := axis.Convert(image.Point{
X: indicatorLen,
Y: gtx.Px(s.Indicator.MinorWidth),
Y: gtx.Dp(s.Indicator.MinorWidth),
})
radius := gtx.Px(s.Indicator.CornerRadius)
radius := gtx.Dp(s.Indicator.CornerRadius)
// Lay out the indicator.
offset := axis.Convert(image.Pt(viewStart, 0))
@@ -247,7 +247,7 @@ func (l ListStyle) Layout(gtx layout.Context, length int, w layout.ListElement)
originalConstraints := gtx.Constraints
// Determine how much space the scrollbar occupies.
barWidth := gtx.Px(l.Width(gtx.Metric))
barWidth := gtx.Dp(l.Width())
if l.AnchorStrategy == Occupy {
+2 -2
View File
@@ -38,7 +38,7 @@ func TestListAnchorStrategies(t *testing.T) {
}
return layout.Dimensions{Size: image.Point{
X: gtx.Constraints.Max.X,
Y: gtx.Px(unit.Dp(20)),
Y: gtx.Dp(20),
}}
}
@@ -47,7 +47,7 @@ func TestListAnchorStrategies(t *testing.T) {
elements := 100
th := material.NewTheme(gofont.Collection())
materialList := material.List(th, &list)
indicatorWidth := gtx.Px(materialList.Width(gtx.Metric))
indicatorWidth := gtx.Dp(materialList.Width())
materialList.AnchorStrategy = material.Occupy
occupyDims := materialList.Layout(gtx, elements, space)
+1 -2
View File
@@ -13,7 +13,6 @@ import (
"gioui.org/op"
"gioui.org/op/clip"
"gioui.org/op/paint"
"gioui.org/unit"
)
type LoaderStyle struct {
@@ -32,7 +31,7 @@ func (l LoaderStyle) Layout(gtx layout.Context) layout.Dimensions {
diam = minY
}
if diam == 0 {
diam = gtx.Px(unit.Dp(24))
diam = gtx.Dp(24)
}
sz := gtx.Constraints.Constrain(image.Pt(diam, diam))
radius := sz.X / 2
+3 -3
View File
@@ -29,10 +29,10 @@ func ProgressBar(th *Theme, progress float32) ProgressBarStyle {
func (p ProgressBarStyle) Layout(gtx layout.Context) layout.Dimensions {
shader := func(width int, color color.NRGBA) layout.Dimensions {
var maxHeight = unit.Dp(4)
rr := gtx.Px(unit.Dp(2))
const maxHeight = unit.Dp(4)
rr := gtx.Dp(2)
d := image.Point{X: width, Y: gtx.Px(maxHeight)}
d := image.Point{X: width, Y: gtx.Dp(maxHeight)}
defer clip.UniformRRect(image.Rectangle{Max: image.Pt(width, d.Y)}, rr).Push(gtx.Ops).Pop()
paint.ColorOp{Color: color}.Add(gtx.Ops)
+1 -2
View File
@@ -10,7 +10,6 @@ import (
"gioui.org/layout"
"gioui.org/op"
"gioui.org/op/paint"
"gioui.org/unit"
)
type ProgressCircleStyle struct {
@@ -31,7 +30,7 @@ func (p ProgressCircleStyle) Layout(gtx layout.Context) layout.Dimensions {
diam = minY
}
if diam == 0 {
diam = gtx.Px(unit.Dp(24))
diam = gtx.Dp(24)
}
sz := gtx.Constraints.Constrain(image.Pt(diam, diam))
radius := sz.X / 2
+2 -3
View File
@@ -5,7 +5,6 @@ package material
import (
"gioui.org/io/semantic"
"gioui.org/layout"
"gioui.org/unit"
"gioui.org/widget"
)
@@ -25,8 +24,8 @@ func RadioButton(th *Theme, group *widget.Enum, key, label string) RadioButtonSt
Color: th.Palette.Fg,
IconColor: th.Palette.ContrastBg,
TextSize: th.TextSize.Scale(14.0 / 16.0),
Size: unit.Dp(26),
TextSize: th.TextSize * 14.0 / 16.0,
Size: 26,
shaper: th.Shaper,
checkedStateIcon: th.Icon.RadioChecked,
uncheckedStateIcon: th.Icon.RadioUnchecked,
+4 -4
View File
@@ -31,19 +31,19 @@ type SliderStyle struct {
Color color.NRGBA
Float *widget.Float
FingerSize unit.Value
FingerSize unit.Dp
}
func (s SliderStyle) Layout(gtx layout.Context) layout.Dimensions {
thumbRadius := gtx.Px(unit.Dp(6))
trackWidth := gtx.Px(unit.Dp(2))
thumbRadius := gtx.Dp(6)
trackWidth := gtx.Dp(2)
axis := s.Float.Axis
// Keep a minimum length so that the track is always visible.
minLength := thumbRadius + 3*thumbRadius + thumbRadius
// Try to expand to finger size, but only if the constraints
// allow for it.
touchSizePx := min(gtx.Px(s.FingerSize), axis.Convert(gtx.Constraints.Max).Y)
touchSizePx := min(gtx.Dp(s.FingerSize), axis.Convert(gtx.Constraints.Max).Y)
sizeMain := max(axis.Convert(gtx.Constraints.Min).X, minLength)
sizeCross := max(2*thumbRadius, touchSizePx)
size := axis.Convert(image.Pt(sizeMain, sizeCross))
+6 -7
View File
@@ -12,7 +12,6 @@ import (
"gioui.org/op"
"gioui.org/op/clip"
"gioui.org/op/paint"
"gioui.org/unit"
"gioui.org/widget"
)
@@ -40,9 +39,9 @@ func Switch(th *Theme, swtch *widget.Bool, description string) SwitchStyle {
// Layout updates the switch and displays it.
func (s SwitchStyle) Layout(gtx layout.Context) layout.Dimensions {
trackWidth := gtx.Px(unit.Dp(36))
trackHeight := gtx.Px(unit.Dp(16))
thumbSize := gtx.Px(unit.Dp(20))
trackWidth := gtx.Dp(36)
trackHeight := gtx.Dp(16)
thumbSize := gtx.Dp(20)
trackOff := (thumbSize - trackHeight) / 2
// Draw track.
@@ -67,7 +66,7 @@ func (s SwitchStyle) Layout(gtx layout.Context) layout.Dimensions {
t.Pop()
// Draw thumb ink.
inkSize := gtx.Px(unit.Dp(44))
inkSize := gtx.Dp(44)
rr := inkSize / 2
inkOff := image.Point{
X: trackWidth/2 - rr,
@@ -107,13 +106,13 @@ func (s SwitchStyle) Layout(gtx layout.Context) layout.Dimensions {
// Draw thumb shadow, a translucent disc slightly larger than the
// thumb itself.
// Center shadow horizontally and slightly adjust its Y.
paint.FillShape(gtx.Ops, argb(0x55000000), circle(thumbRadius, thumbRadius+gtx.Px(unit.Dp(.25)), thumbRadius+1))
paint.FillShape(gtx.Ops, argb(0x55000000), circle(thumbRadius, thumbRadius+gtx.Dp(.25), thumbRadius+1))
// Draw thumb.
paint.FillShape(gtx.Ops, col, circle(thumbRadius, thumbRadius, thumbRadius))
// Set up click area.
clickSize := gtx.Px(unit.Dp(40))
clickSize := gtx.Dp(40)
clickOff := image.Point{
X: (thumbSize - clickSize) / 2,
Y: (trackHeight-clickSize)/2 + trackOff,
+4 -4
View File
@@ -34,7 +34,7 @@ type Palette struct {
type Theme struct {
Shaper text.Shaper
Palette
TextSize unit.Value
TextSize unit.Sp
Icon struct {
CheckBoxChecked *widget.Icon
CheckBoxUnchecked *widget.Icon
@@ -43,7 +43,7 @@ type Theme struct {
}
// FingerSize is the minimum touch target size.
FingerSize unit.Value
FingerSize unit.Dp
}
func NewTheme(fontCollection []text.FontFace) *Theme {
@@ -56,7 +56,7 @@ func NewTheme(fontCollection []text.FontFace) *Theme {
ContrastBg: rgb(0x3f51b5),
ContrastFg: rgb(0xffffff),
}
t.TextSize = unit.Sp(16)
t.TextSize = 16
t.Icon.CheckBoxChecked = mustIcon(widget.NewIcon(icons.ToggleCheckBox))
t.Icon.CheckBoxUnchecked = mustIcon(widget.NewIcon(icons.ToggleCheckBoxOutlineBlank))
@@ -64,7 +64,7 @@ func NewTheme(fontCollection []text.FontFace) *Theme {
t.Icon.RadioUnchecked = mustIcon(widget.NewIcon(icons.ToggleRadioButtonUnchecked))
// 38dp is on the lower end of possible finger size.
t.FingerSize = unit.Dp(38)
t.FingerSize = 38
return t
}