Inline Plugin
# Init?(go)
1package inline
2
3import (
4 "gui/cstyle"
5 "gui/element"
6 "gui/utils"
7)
8
9func Init() cstyle.Plugin {
10 return cstyle.Plugin{
11 Styles: map[string]string{
12 "display": "inline",
13 },
14 Level: 1,
15 Handler: func(n *element.Node, state *map[string]element.State) {
16 s := *state
17 self := s[n.Properties.Id]
18 parent := s[n.Parent.Properties.Id]
19 copyOfX := self.X
20 copyOfY := self.Y
21 xCollect := float32(0)
22 for i, v := range n.Parent.Children {
23 vState := s[v.Properties.Id]
24 if vState.Style["position"] != "absolute" {
25 if vState.Style["display"] != "inline" {
26 xCollect = 0
27 } else {
28 if v.Properties.Id == n.Properties.Id {
29 if self.X+xCollect+self.Width > ((parent.Width)-parent.Padding.Right)+parent.X && i > 0 {
30 // Break Node
31 sibling := s[n.Parent.Children[i-1].Properties.Id]
32 self.Y += sibling.Height
33 self.X = copyOfX
34 alignText(n, s, i, state)
35 } else if i > 0 {
36 // Node did not break
37 self.X += xCollect
38 }
39 break
40 } else {
41 if vState.Style["display"] == "inline" {
42 if colliderDetection(vState, self) {
43 xCollect += vState.Width
44 } else {
45 xCollect = 0
46 }
47 }
48 }
49 }
50 }
51 }
52 // !ISSUE: need to align after the end of the block not just the breaks
53 // alignText(n, s, len(n.Parent.Children)-1, state)
54 propagateOffsets(n, copyOfX, copyOfY, self, state)
55 (*state)[n.Properties.Id] = self
56 },
57 }
58}
59
60func propagateOffsets(n *element.Node, copyOfX, copyOfY float32, self element.State, state *map[string]element.State) {
61 s := *state
62 for _, v := range n.Children {
63 vState := s[v.Properties.Id]
64 vState.X += self.X - copyOfX
65 vState.Y += self.Y - copyOfY
66 if len(v.Children) > 0 {
67 propagateOffsets(&v, copyOfX, copyOfY, self, state)
68 }
69 (*state)[v.Properties.Id] = vState
70 }
71}
72
73func colliderDetection(s1, s2 element.State) bool {
74 s1Min := s1.Y
75 s1Max := s1.Y + s1.Height
76 s2Min := s2.Y
77 s2Max := s2.Y + s2.Height
78 return s1Min > s2Min && s1Min < s2Max || s1Max > s2Min && s1Min < s2Max || s2Min > s1Min && s2Min < s1Max || s2Max > s1Min && s2Min < s1Max
79}
80
81func alignText(n *element.Node, s map[string]element.State, i int, state *map[string]element.State) {
82 tallest := float32(0)
83 endex := 0
84 for a := i; a > 0; a-- {
85 if s[n.Parent.Children[a].Properties.Id].Y != s[n.Parent.Children[i-1].Properties.Id].Y {
86 endex = a
87 break
88 } else {
89 tallest = utils.Max(tallest, s[n.Parent.Children[a].Properties.Id].Height)
90 }
91 }
92 // !ISSUE: Find a better way then -4
93 for a := i; a > endex-1; a-- {
94 p := (*state)[n.Parent.Children[a].Properties.Id]
95 if p.Height != tallest {
96 p.Y += (tallest - p.Height) - 5
97 (*state)[n.Parent.Children[a].Properties.Id] = p
98 }
99 }
100 for a := i; a < len(n.Parent.Children)-1; a++ {
101 p := (*state)[n.Parent.Children[a].Properties.Id]
102 p.Y += 7
103 (*state)[n.Parent.Children[a].Properties.Id] = p
104 }
105}