-
Notifications
You must be signed in to change notification settings - Fork 103
/
padding.go
108 lines (91 loc) · 2.28 KB
/
padding.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package render
import (
"image"
"image/color"
"github.com/tidbyt/gg"
)
type Insets struct {
Left int
Top int
Right int
Bottom int
}
// Padding places padding around its child.
//
// If the `pad` attribute is a single integer, that amount of padding
// will be placed on all sides of the child. If it's a 4-tuple `(left,
// top, right, bottom)`, then padding will be placed on the sides
// accordingly.
//
// DOC(Child): The Widget to place padding around
// DOC(Expanded): This is a confusing parameter
// DOC(Pad): Padding around the child
// DOC(Color): Background color
type Padding struct {
Widget
Child Widget `starlark:"child,required"`
Pad Insets
Expanded bool
Color color.Color
}
func (p Padding) PaintBounds(bounds image.Rectangle, frameIdx int) image.Rectangle {
cb := p.Child.PaintBounds(
image.Rect(0, 0, bounds.Dx()-p.Pad.Left-p.Pad.Right, bounds.Dy()-p.Pad.Top-p.Pad.Bottom),
frameIdx,
)
var width, height int
if p.Expanded {
width = bounds.Dx()
height = bounds.Dy()
} else {
width = cb.Dx() + p.Pad.Left + p.Pad.Right
height = cb.Dy() + p.Pad.Top + p.Pad.Bottom
}
return image.Rect(0, 0, width, height)
}
func (p Padding) Paint(dc *gg.Context, bounds image.Rectangle, frameIdx int) {
cb := p.Child.PaintBounds(
image.Rect(0, 0, bounds.Dx()-p.Pad.Left-p.Pad.Right, bounds.Dy()-p.Pad.Top-p.Pad.Bottom),
frameIdx,
)
var width, height int
if p.Expanded {
width = bounds.Dx()
height = bounds.Dy()
} else {
width = cb.Dx() + p.Pad.Left + p.Pad.Right
height = cb.Dy() + p.Pad.Top + p.Pad.Bottom
}
if p.Color != nil {
dc.SetColor(p.Color)
dc.DrawRectangle(0, 0, float64(width), float64(height))
dc.Fill()
}
dc.Push()
// Some apps use negative padding as a positioning hack.
clipLeft := p.Pad.Left
clipTop := p.Pad.Top
if clipLeft < 0 {
clipLeft = 0
}
if clipTop < 0 {
clipTop = 0
}
dc.DrawRectangle(
float64(clipLeft),
float64(clipTop),
float64(width-p.Pad.Left-p.Pad.Right),
float64(height-p.Pad.Top-p.Pad.Bottom),
)
dc.Clip()
dc.Translate(float64(p.Pad.Left), float64(p.Pad.Top))
p.Child.Paint(dc, image.Rect(0, 0, bounds.Dx()-p.Pad.Left-p.Pad.Right, bounds.Dy()-p.Pad.Top-p.Pad.Bottom),
frameIdx)
dc.Pop()
}
func (p Padding) FrameCount() int {
if p.Child != nil {
return p.Child.FrameCount()
}
return 1
}