github.com/gop9/olt@v0.0.0-20200202132135-d956aad50b08/framework/util.go (about) 1 package framework 2 3 import ( 4 "github.com/gop9/olt/framework/font" 5 nstyle "github.com/gop9/olt/framework/style" 6 "github.com/gop9/olt/gio/io/pointer" 7 "image" 8 9 "github.com/gop9/olt/framework/rect" 10 ) 11 12 type Heading int 13 14 const ( 15 Up Heading = iota 16 Right 17 Down 18 Left 19 ) 20 21 func min(a, b int) int { 22 if a < b { 23 return a 24 } 25 return b 26 } 27 28 func max(a, b int) int { 29 if a > b { 30 return a 31 } 32 return b 33 } 34 35 func triangleFromDirection(r rect.Rect, pad_x, pad_y int, direction Heading) (result [3]image.Point) { 36 var w_half int 37 var h_half int 38 39 r.W = max(2*pad_x, r.W) 40 r.H = max(2*pad_y, r.H) 41 r.W = r.W - 2*pad_x 42 r.H = r.H - 2*pad_y 43 44 r.X = r.X + pad_x 45 r.Y = r.Y + pad_y 46 47 w_half = r.W / 2.0 48 h_half = r.H / 2.0 49 50 if direction == Up { 51 result[0] = image.Point{r.X + w_half, r.Y} 52 result[1] = image.Point{r.X + r.W, r.Y + r.H} 53 result[2] = image.Point{r.X, r.Y + r.H} 54 } else if direction == Right { 55 result[0] = image.Point{r.X, r.Y} 56 result[1] = image.Point{r.X + r.W, r.Y + h_half} 57 result[2] = image.Point{r.X, r.Y + r.H} 58 } else if direction == Down { 59 result[0] = image.Point{r.X, r.Y} 60 result[1] = image.Point{r.X + r.W, r.Y} 61 result[2] = image.Point{r.X + w_half, r.Y + r.H} 62 } else { 63 result[0] = image.Point{r.X, r.Y + h_half} 64 result[1] = image.Point{r.X + r.W, r.Y} 65 result[2] = image.Point{r.X + r.W, r.Y + r.H} 66 } 67 return 68 } 69 70 func minFloat(x, y float64) float64 { 71 if x < y { 72 return x 73 } 74 return y 75 } 76 77 func maxFloat(x, y float64) float64 { 78 if x > y { 79 return x 80 } 81 return y 82 } 83 84 func clampFloat(i, v, x float64) float64 { 85 if v < i { 86 v = i 87 } 88 if v > x { 89 v = x 90 } 91 return v 92 } 93 94 func clampInt(i, v, x int) int { 95 if v < i { 96 v = i 97 } 98 if v > x { 99 v = x 100 } 101 return v 102 } 103 104 func saturateFloat(x float64) float64 { 105 return maxFloat(0.0, minFloat(1.0, x)) 106 } 107 108 func basicWidgetStateControl(state *nstyle.WidgetStates, in *Input, bounds rect.Rect) nstyle.WidgetStates { 109 if in == nil { 110 *state = nstyle.WidgetStateInactive 111 return nstyle.WidgetStateInactive 112 } 113 114 hovering := in.Mouse.HoveringRect(bounds) 115 116 if *state == nstyle.WidgetStateInactive && hovering { 117 *state = nstyle.WidgetStateHovered 118 } 119 120 if *state == nstyle.WidgetStateHovered && !hovering { 121 *state = nstyle.WidgetStateInactive 122 } 123 124 if *state == nstyle.WidgetStateHovered && in.Mouse.HasClickInRect(pointer.ButtonLeft, bounds) { 125 *state = nstyle.WidgetStateActive 126 } 127 128 if hovering { 129 return nstyle.WidgetStateHovered 130 } else { 131 return nstyle.WidgetStateInactive 132 } 133 } 134 135 func shrinkRect(r rect.Rect, amount int) rect.Rect { 136 var res rect.Rect 137 r.W = max(r.W, 2*amount) 138 r.H = max(r.H, 2*amount) 139 res.X = r.X + amount 140 res.Y = r.Y + amount 141 res.W = r.W - 2*amount 142 res.H = r.H - 2*amount 143 return res 144 } 145 146 func FontHeight(f font.Face) int { 147 return f.Metrics().Ascent.Ceil() + f.Metrics().Descent.Ceil() 148 } 149 150 func unify(a rect.Rect, b rect.Rect) (clip rect.Rect) { 151 clip.X = max(a.X, b.X) 152 clip.Y = max(a.Y, b.Y) 153 clip.W = min(a.X+a.W, b.X+b.W) - clip.X 154 clip.H = min(a.Y+a.H, b.Y+b.H) - clip.Y 155 clip.W = max(0.0, clip.W) 156 clip.H = max(0.0, clip.H) 157 return 158 } 159 160 func padRect(r rect.Rect, pad image.Point) rect.Rect { 161 r.W = max(r.W, 2*pad.X) 162 r.H = max(r.H, 2*pad.Y) 163 r.X += pad.X 164 r.Y += pad.Y 165 r.W -= 2 * pad.X 166 r.H -= 2 * pad.Y 167 return r 168 }