github.com/gop9/olt@v0.0.0-20200202132135-d956aad50b08/gio/unit/unit.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 /* 4 5 Package unit implements device independent units and values. 6 7 A Value is a value with a Unit attached. 8 9 Device independent pixel, or dp, is the unit for sizes independent of 10 the underlying display device. 11 12 Scaled pixels, or sp, is the unit for text sizes. An sp is like dp with 13 text scaling applied. 14 15 Finally, pixels, or px, is the unit for display dependent pixels. Their 16 size vary between platforms and displays. 17 18 To maintain a constant visual size across platforms and displays, always 19 use dps or sps to define user interfaces. Only use pixels for derived 20 values. 21 22 */ 23 package unit 24 25 import "fmt" 26 27 // Value is a value with a unit. 28 type Value struct { 29 V float32 30 U Unit 31 } 32 33 // Unit represents a unit for a Value. 34 type Unit uint8 35 36 // Converter converts Values to pixels. 37 type Converter interface { 38 Px(v Value) int 39 } 40 41 const ( 42 // UnitPx represent device pixels in the resolution of 43 // the underlying display. 44 UnitPx Unit = iota 45 // UnitDp represents device independent pixels. 1 dp will 46 // have the same apparent size across platforms and 47 // display resolutions. 48 UnitDp 49 // UnitSp is like UnitDp but for font sizes. 50 UnitSp 51 ) 52 53 // Px returns the Value for v device pixels. 54 func Px(v float32) Value { 55 return Value{V: v, U: UnitPx} 56 } 57 58 // Px returns the Value for v device independent 59 // pixels. 60 func Dp(v float32) Value { 61 return Value{V: v, U: UnitDp} 62 } 63 64 // Sp returns the Value for v scaled dps. 65 func Sp(v float32) Value { 66 return Value{V: v, U: UnitSp} 67 } 68 69 // Scale returns the value scaled by s. 70 func (v Value) Scale(s float32) Value { 71 v.V *= s 72 return v 73 } 74 75 func (v Value) String() string { 76 return fmt.Sprintf("%g%s", v.V, v.U) 77 } 78 79 func (u Unit) String() string { 80 switch u { 81 case UnitPx: 82 return "px" 83 case UnitDp: 84 return "dp" 85 case UnitSp: 86 return "sp" 87 default: 88 panic("unknown unit") 89 } 90 } 91 92 // Add a list of Values. 93 func Add(c Converter, values ...Value) Value { 94 var sum Value 95 for _, v := range values { 96 sum, v = compatible(c, sum, v) 97 sum.V += v.V 98 } 99 return sum 100 } 101 102 // Max returns the maximum of a list of Values. 103 func Max(c Converter, values ...Value) Value { 104 var max Value 105 for _, v := range values { 106 max, v = compatible(c, max, v) 107 if v.V > max.V { 108 max.V = v.V 109 } 110 } 111 return max 112 } 113 114 func compatible(c Converter, v1, v2 Value) (Value, Value) { 115 if v1.U == v2.U { 116 return v1, v2 117 } 118 if v1.V == 0 { 119 v1.U = v2.U 120 return v1, v2 121 } 122 if v2.V == 0 { 123 v2.U = v1.U 124 return v1, v2 125 } 126 return Px(float32(c.Px(v1))), Px(float32(c.Px(v2))) 127 }