Commits
Diff
diff --git a/cstyle/plugins/flex/main.go b/cstyle/plugins/flex/main.go
index e39cc1c..cf92289 100644
--- a/cstyle/plugins/flex/main.go
+++ b/cstyle/plugins/flex/main.go
@@ -56,3 +56,3 @@ func Init() cstyle.Plugin {
- alignItems := n.Style["align-items"]
- if alignItems == "" {
- alignItems = "normal"
+ vAlign := n.Style["align-items"]
+ if vAlign == "" {
+ vAlign = "normal"
@@ -204 +204 @@ func Init() cstyle.Plugin {
- vState.Height = getMinHeight(v, state, sib.Height)
+ vState.Height = sib.Height
@@ -228 +228 @@ func Init() cstyle.Plugin {
- vState.Height = getMinHeight(v, state, h)
+ vState.Height = h
@@ -239 +239 @@ func Init() cstyle.Plugin {
- vState.Height = getMinHeight(n.Children[i], state, float32(v[2]))
+ vState.Height = float32(v[2])
@@ -251,3 +250,0 @@ func Init() cstyle.Plugin {
-
- alignItemsRow(rows, n, state, alignItems)
-
@@ -270,19 +267,16 @@ func applyBlock(n *element.Node, state *map[string]element.State) {
- if len(n.Children) > 0 {
- accum := float32(0)
- inlineOffset := float32(0)
- s := *state
- lastHeight := float32(0)
- baseY := s[n.Children[0].Properties.Id].Y
- for i := 0; i < len(n.Children); i++ {
- v := &n.Children[i]
- vState := s[v.Properties.Id]
-
- if v.Style["display"] != "block" {
- vState.Y += inlineOffset
- accum = (vState.Y - baseY)
- lastHeight = vState.Height
- } else if v.Style["position"] != "absolute" {
- vState.Y += accum
- inlineOffset += (vState.Height + (vState.Border.Width * 2) + vState.Margin.Top + vState.Margin.Bottom + vState.Padding.Top + vState.Padding.Bottom) + lastHeight
- }
- (*state)[v.Properties.Id] = vState
+ accum := float32(0)
+ inlineOffset := float32(0)
+ s := *state
+ lastHeight := float32(0)
+ baseY := s[n.Children[0].Properties.Id].Y
+ for i := 0; i < len(n.Children); i++ {
+ v := &n.Children[i]
+ vState := s[v.Properties.Id]
+
+ if v.Style["display"] != "block" {
+ vState.Y += inlineOffset
+ accum = (vState.Y - baseY)
+ lastHeight = vState.Height
+ } else if v.Style["position"] != "absolute" {
+ vState.Y += accum
+ inlineOffset += (vState.Height + (vState.Border.Width * 2) + vState.Margin.Top + vState.Margin.Bottom + vState.Padding.Top + vState.Padding.Bottom) + lastHeight
@@ -289,0 +284 @@ func applyBlock(n *element.Node, state *map[string]element.State) {
+ (*state)[v.Properties.Id] = vState
@@ -378,12 +372,0 @@ func countText(n element.Node) int {
-func getMinHeight(n element.Node, state *map[string]element.State, prev float32) float32 {
- s := *state
- self := s[n.Properties.Id]
- if n.Style["min-height"] != "" {
- mw := utils.ConvertToPixels(n.Style["min-height"], self.EM, s[n.Parent.Properties.Id].Width)
- return utils.Max(prev, mw)
- } else {
- return prev
- }
-
-}
-
@@ -402,4 +384,0 @@ func getMinWidth(n *element.Node, state *map[string]element.State) float32 {
- if n.Style["min-width"] != "" {
- mw := utils.ConvertToPixels(n.Style["min-width"], self.EM, s[n.Parent.Properties.Id].Width)
- selfWidth = utils.Max(mw, selfWidth)
- }
@@ -742,61 +721 @@ func justifyRow(rows [][]int, n *element.Node, state *map[string]element.State,
-func alignItemsRow(rows [][]int, n *element.Node, state *map[string]element.State, align string) {
- // needs
- // baseline - top
- // flex-start
- // self-start
- // start
-
- // center - middle
-
- // end - end
- // flex-end
- // self-end
-
- props := []string{
- "baseline",
- "flex-start",
- "self-start",
- "start",
- "center",
- "end",
- "flex-end",
- "self-end",
- }
-
- matches := false
- for _, v := range props {
- if align == v {
- matches = true
- break
- }
- }
-
- if !matches {
- return
- }
-
- s := *state
- self := s[n.Properties.Id]
-
- maxes := []float32{}
- var maxesTotal float32
-
- for _, row := range rows {
- var maxH float32
- for i := row[0]; i < row[1]; i++ {
- vState := s[n.Children[i].Properties.Id]
- _, h := getInnerSize(&n.Children[i], state)
- h = getMinHeight(n.Children[i], state, h)
- vState.Height = h
- h += vState.Margin.Top + vState.Margin.Bottom + (vState.Border.Width * 2)
- maxH = utils.Max(maxH, h)
- // this doesn't work, don't try again
- // maxH -= vState.Border.Width
-
- (*state)[n.Children[i].Properties.Id] = vState
- }
- maxes = append(maxes, maxH)
- maxesTotal += maxH
- }
-
- os := ((self.Height - (self.Margin.Top + self.Margin.Bottom + (self.Border.Width * 2))) - maxesTotal) / float32(len(rows)+1)
+// func alignItemsRow(rows [][]int, n *element.Node, state *map[string]element.State, justify string, reversed bool) {
@@ -804,35 +723 @@ func alignItemsRow(rows [][]int, n *element.Node, state *map[string]element.Stat
- for c, row := range rows {
- maxH := maxes[c]
- if align == "start" || align == "flex-start" || align == "self-start" {
- for i := row[0]; i < row[1]; i++ {
- vState := s[n.Children[i].Properties.Id]
- offset := (vState.Y + (os * float32(c)) + vState.Margin.Top + vState.Border.Width)
- propagateOffsets(&n.Children[i], vState.X, vState.Y, vState.X, offset, state)
- vState.Y = offset
- (*state)[n.Children[i].Properties.Id] = vState
- }
- } else if align == "center" {
- for i := row[0]; i < row[1]; i++ {
- vState := s[n.Children[i].Properties.Id]
-
- offset := (vState.Y + (os*float32(c))/2)
- if vState.Height+vState.Margin.Top+vState.Margin.Bottom+(vState.Border.Width*2) < maxH {
- offset += (maxH - (vState.Height + vState.Margin.Top + vState.Border.Width)) / 2
- } else {
- offset += vState.Margin.Top + vState.Border.Width
- }
- propagateOffsets(&n.Children[i], vState.X, vState.Y, vState.X, offset, state)
- vState.Y = offset
- (*state)[n.Children[i].Properties.Id] = vState
- }
- } else if align == "end" || align == "flex-end" || align == "self-end" {
- for i := row[0]; i < row[1]; i++ {
- vState := s[n.Children[i].Properties.Id]
- offset := ((vState.Y + (os * float32(c+1))) + (maxH - (vState.Height + vState.Margin.Top + vState.Border.Width)))
- propagateOffsets(&n.Children[i], vState.X, vState.Y, vState.X, offset, state)
- vState.Y = offset
- (*state)[n.Children[i].Properties.Id] = vState
- }
- }
- }
-}
+// }
package flex
import (
"gui/cstyle"
"gui/cstyle/plugins/inline"
"gui/element"
"gui/utils"
"sort"
"strings"
)
// !ISSUES: Text disapearing (i think its the inline plugin)
// + widths
// + wrpa wraps too soon
func Init() cstyle.Plugin {
return cstyle.Plugin{
Selector: func(n *element.Node) bool {
styles := map[string]string{
"display": "flex",
}
matches := true
for name, value := range styles {
if (n.Style[name] != value || n.Style[name] == "") && !(value == "*") {
matches = false
}
}
return matches
},
Level: 3,
Handler: func(n *element.Node, state *map[string]element.State) {
s := *state
self := s[n.Properties.Id]
verbs := strings.Split(n.Style["flex-direction"], "-")
flexDirection := verbs[0]
if flexDirection == "" {
flexDirection = "row"
}
flexReversed := false
if len(verbs) > 1 {
flexReversed = true
}
var flexWrapped bool
if n.Style["flex-wrap"] == "wrap" {
flexWrapped = true
} else {
flexWrapped = false
}
hAlign := n.Style["align-content"]
if hAlign == "" {
hAlign = "normal"
}
alignItems := n.Style["align-items"]
if alignItems == "" {
alignItems = "normal"
}
justifyItems := n.Style["justify-items"]
if justifyItems == "" {
justifyItems = "normal"
}
justifyContent := n.Style["justify-content"]
if justifyContent == "" {
justifyContent = "normal"
}
// fmt.Println(flexDirection, flexReversed, flexWrapped, hAlign, vAlign, justifyItems, justifyContent)
if flexDirection == "row" {
rows := [][]int{}
maxH := float32(0)
// Get inital sizing
textTotal := 0
textCounts := []int{}
widths := []float32{}
innerSizes := [][]float32{}
minWidths := []float32{}
maxWidths := []float32{}
for _, v := range n.Children {
count := countText(v)
textTotal += count
textCounts = append(textCounts, count)
minw := getMinWidth(&v, state)
minWidths = append(minWidths, minw)
maxw := getMaxWidth(&v, state)
maxWidths = append(maxWidths, maxw)
w, h := getInnerSize(&v, state)
innerSizes = append(innerSizes, []float32{w, h})
}
selfWidth := (self.Width - self.Padding.Left) - self.Padding.Right
// if the elements are less than the size of the parent, don't change widths. Just set mins
if !flexWrapped {
if add2d(innerSizes, 0) < selfWidth {
for i, v := range n.Children {
vState := s[v.Properties.Id]
w := innerSizes[i][0]
w -= vState.Margin.Left + vState.Margin.Right + (vState.Border.Width * 2)
widths = append(widths, w)
}
} else {
// Modifiy the widths so they aren't under the mins
for i, v := range n.Children {
vState := s[v.Properties.Id]
w := ((selfWidth / float32(textTotal)) * float32(textCounts[i]))
w -= vState.Margin.Left + vState.Margin.Right + (vState.Border.Width * 2)
if w < minWidths[i] {
selfWidth -= minWidths[i] + vState.Margin.Left + vState.Margin.Right + (vState.Border.Width * 2)
textTotal -= textCounts[i]
textCounts[i] = 0
}
}
for i, v := range n.Children {
vState := s[v.Properties.Id]
w := ((selfWidth / float32(textTotal)) * float32(textCounts[i]))
w -= vState.Margin.Left + vState.Margin.Right + (vState.Border.Width * 2)
// (w!=w) is of NaN
if w < minWidths[i] || (w != w) {
w = minWidths[i]
}
widths = append(widths, w)
}
}
// Apply the new widths
fState := s[n.Children[0].Properties.Id]
for i, v := range n.Children {
vState := s[v.Properties.Id]
vState.Width = widths[i]
xStore := vState.X
if i > 0 {
sState := s[n.Children[i-1].Properties.Id]
vState.X = sState.X + sState.Width + sState.Margin.Right + vState.Margin.Left + sState.Border.Width + vState.Border.Width
propagateOffsets(&v, xStore, vState.Y, vState.X, fState.Y, state)
}
vState.Y = fState.Y
(*state)[v.Properties.Id] = vState
deInline(&v, state)
applyInline(&v, state)
applyBlock(&v, state)
_, h := getInnerSize(&v, state)
h = utils.Max(h, vState.Height)
maxH = utils.Max(maxH, h)
}
// When not wrapping everything will be on the same row
rows = append(rows, []int{0, len(n.Children), int(maxH)})
} else {
// Flex Wrapped
sum := innerSizes[0][0]
for i := 0; i < len(n.Children); i++ {
v := n.Children[i]
vState := s[v.Properties.Id]
// if the next plus current will break then
w := innerSizes[i][0]
if i > 0 {
sib := s[n.Children[i-1].Properties.Id]
if maxWidths[i] > selfWidth {
w = selfWidth - vState.Margin.Left - vState.Margin.Right - (vState.Border.Width * 2)
}
if w+sum > selfWidth {
sum = w + vState.Margin.Left + vState.Margin.Right + (vState.Border.Width * 2)
} else {
propagateOffsets(&v, vState.X, vState.Y, vState.X, sib.Y, state)
vState.Y = sib.Y
(*state)[v.Properties.Id] = vState
sum += w + vState.Margin.Left + vState.Margin.Right + (vState.Border.Width * 2)
}
}
widths = append(widths, w)
}
// Move the elements into the correct position
start := 0
var prevOffset float32
for i := 0; i < len(n.Children); i++ {
v := n.Children[i]
vState := s[v.Properties.Id]
vState.Width = widths[i]
xStore := vState.X
yStore := vState.Y
if i > 0 {
sib := s[n.Children[i-1].Properties.Id]
if vState.Y+prevOffset == sib.Y {
yStore += prevOffset
if vState.Height < sib.Height {
vState.Height = getMinHeight(v, state, sib.Height)
}
// Shift right if on a row with sibling
xStore = sib.X + sib.Width + sib.Margin.Right + sib.Border.Width + vState.Margin.Left + vState.Border.Width
} else {
// Shift under sibling
yStore = sib.Y + sib.Height + sib.Margin.Top + sib.Margin.Bottom + sib.Border.Width*2
prevOffset = yStore - vState.Y
rows = append(rows, []int{start, i, int(maxH)})
start = i
maxH = 0
}
propagateOffsets(&v, vState.X, vState.Y, xStore, yStore, state)
}
vState.X = xStore
vState.Y = yStore
(*state)[v.Properties.Id] = vState
deInline(&v, state)
applyInline(&v, state)
applyBlock(&v, state)
_, h := getInnerSize(&v, state)
h = utils.Max(h, vState.Height)
maxH = utils.Max(maxH, h)
vState.Height = getMinHeight(v, state, h)
(*state)[v.Properties.Id] = vState
}
if start < len(n.Children) {
rows = append(rows, []int{start, len(n.Children), int(maxH)})
}
}
for _, v := range rows {
for i := v[0]; i < v[1]; i++ {
vState := s[n.Children[i].Properties.Id]
vState.Height = getMinHeight(n.Children[i], state, float32(v[2]))
(*state)[n.Children[i].Properties.Id] = vState
}
}
// Reverse elements
if flexReversed {
rowReverse(rows, n, state)
}
if justifyContent != "" && justifyContent != "normal" {
justifyRow(rows, n, state, justifyContent, flexReversed)
}
alignItemsRow(rows, n, state, alignItems)
}
// Column doesn't really need a lot done bc it is basically block styling rn
if flexDirection == "column" && flexReversed {
colReverse(n, state)
}
if n.Style["height"] == "" {
_, h := getInnerSize(n, state)
self.Height = h
}
(*state)[n.Properties.Id] = self
},
}
}
func applyBlock(n *element.Node, state *map[string]element.State) {
if len(n.Children) > 0 {
accum := float32(0)
inlineOffset := float32(0)
s := *state
lastHeight := float32(0)
baseY := s[n.Children[0].Properties.Id].Y
for i := 0; i < len(n.Children); i++ {
v := &n.Children[i]
vState := s[v.Properties.Id]
if v.Style["display"] != "block" {
vState.Y += inlineOffset
accum = (vState.Y - baseY)
lastHeight = vState.Height
} else if v.Style["position"] != "absolute" {
vState.Y += accum
inlineOffset += (vState.Height + (vState.Border.Width * 2) + vState.Margin.Top + vState.Margin.Bottom + vState.Padding.Top + vState.Padding.Bottom) + lastHeight
}
(*state)[v.Properties.Id] = vState
}
}
}
func deInline(n *element.Node, state *map[string]element.State) {
s := *state
// self := s[n.Properties.Id]
baseX := float32(-1)
baseY := float32(-1)
for _, v := range n.Children {
vState := s[v.Properties.Id]
if v.Style["display"] == "inline" {
if baseX < 0 && baseY < 0 {
baseX = vState.X
baseY = vState.Y
} else {
vState.X = baseX
vState.Y = baseY
(*state)[v.Properties.Id] = vState
}
} else {
baseX = float32(-1)
baseY = float32(-1)
}
if len(v.Children) > 0 {
deInline(&v, state)
}
}
}
func applyInline(n *element.Node, state *map[string]element.State) {
pl := inline.Init()
for i := 0; i < len(n.Children); i++ {
v := &n.Children[i]
if len(v.Children) > 0 {
applyInline(v, state)
}
if pl.Selector(v) {
pl.Handler(v, state)
}
}
}
func propagateOffsets(n *element.Node, prevx, prevy, newx, newy float32, state *map[string]element.State) {
s := *state
for _, v := range n.Children {
vState := s[v.Properties.Id]
xStore := (vState.X - prevx) + newx
yStore := (vState.Y - prevy) + newy
if len(v.Children) > 0 {
propagateOffsets(&v, vState.X, vState.Y, xStore, yStore, state)
}
vState.X = xStore
vState.Y = yStore
(*state)[v.Properties.Id] = vState
}
}
func countText(n element.Node) int {
count := 0
groups := []int{}
for _, v := range n.Children {
if v.TagName == "notaspan" {
count += 1
}
if v.Style["display"] == "block" {
groups = append(groups, count)
count = 0
}
if len(v.Children) > 0 {
count += countText(v)
}
}
groups = append(groups, count)
sort.Slice(groups, func(i, j int) bool {
return groups[i] > groups[j]
})
return groups[0]
}
func getMinHeight(n element.Node, state *map[string]element.State, prev float32) float32 {
s := *state
self := s[n.Properties.Id]
if n.Style["min-height"] != "" {
mw := utils.ConvertToPixels(n.Style["min-height"], self.EM, s[n.Parent.Properties.Id].Width)
return utils.Max(prev, mw)
} else {
return prev
}
}
func getMinWidth(n *element.Node, state *map[string]element.State) float32 {
s := *state
self := s[n.Properties.Id]
selfWidth := float32(0)
if len(n.Children) > 0 {
for _, v := range n.Children {
selfWidth = utils.Max(selfWidth, getNodeWidth(&v, state))
}
} else {
selfWidth = self.Width
}
if n.Style["min-width"] != "" {
mw := utils.ConvertToPixels(n.Style["min-width"], self.EM, s[n.Parent.Properties.Id].Width)
selfWidth = utils.Max(mw, selfWidth)
}
selfWidth += self.Padding.Left + self.Padding.Right
return selfWidth
}
func getMaxWidth(n *element.Node, state *map[string]element.State) float32 {
s := *state
self := s[n.Properties.Id]
selfWidth := float32(0)
if len(n.Children) > 0 {
for _, v := range n.Children {
selfWidth += getNodeWidth(&v, state)
}
} else {
selfWidth = self.Width
}
selfWidth += self.Padding.Left + self.Padding.Right
return selfWidth
}
func getNodeWidth(n *element.Node, state *map[string]element.State) float32 {
s := *state
self := s[n.Properties.Id]
w := float32(0)
w += self.Padding.Left
w += self.Padding.Right
w += self.Margin.Left
w += self.Margin.Right
w += self.Width
w += self.Border.Width * 2
for _, v := range n.Children {
w = utils.Max(w, getNodeWidth(&v, state))
}
return w
}
func getInnerSize(n *element.Node, state *map[string]element.State) (float32, float32) {
s := *state
self := s[n.Properties.Id]
minx := float32(10e10)
maxw := float32(0)
miny := float32(10e10)
maxh := float32(0)
for _, v := range n.Children {
vState := s[v.Properties.Id]
minx = utils.Min(vState.X, minx)
miny = utils.Min(vState.Y, miny)
hOffset := (vState.Border.Width * 2) + vState.Margin.Top + vState.Margin.Bottom
wOffset := (vState.Border.Width * 2) + vState.Margin.Left + vState.Margin.Right
maxw = utils.Max(vState.X+vState.Width+wOffset, maxw)
maxh = utils.Max(vState.Y+vState.Height+hOffset, maxh)
}
w := maxw - minx
h := maxh - miny
// !ISSUE: this is a hack to get things moving adding 13 is random
w += self.Padding.Left + self.Padding.Right + 13
h += self.Padding.Top + self.Padding.Bottom
if n.Style["width"] != "" {
w = self.Width
}
if n.Style["height"] != "" {
h = self.Height
}
return w, h
}
func add2d(arr [][]float32, index int) float32 {
var sum float32
if len(arr) == 0 {
return sum
}
for i := 0; i < len(arr); i++ {
if len(arr[i]) <= index {
return sum
}
sum += arr[i][index]
}
return sum
}
func colReverse(n *element.Node, state *map[string]element.State) {
s := *state
tempNodes := []element.Node{}
tempStates := []element.State{}
for i := len(n.Children) - 1; i >= 0; i-- {
tempNodes = append(tempNodes, n.Children[i])
tempStates = append(tempStates, s[n.Children[i].Properties.Id])
}
for i := 0; i < len(tempStates); i++ {
vState := s[n.Children[i].Properties.Id]
propagateOffsets(&n.Children[i], vState.X, vState.Y, vState.X, tempStates[i].Y, state)
vState.Y = tempStates[i].Y
(*state)[n.Children[i].Properties.Id] = vState
}
n.Children = tempNodes
}
func rowReverse(rows [][]int, n *element.Node, state *map[string]element.State) {
s := *state
for _, row := range rows {
tempNodes := []element.Node{}
tempStates := []element.State{}
for i := row[1] - 1; i >= row[0]; i-- {
tempNodes = append(tempNodes, n.Children[i])
tempStates = append(tempStates, s[n.Children[i].Properties.Id])
}
for i := 0; i < len(tempStates); i++ {
e := row[0] + i
vState := s[n.Children[e].Properties.Id]
propagateOffsets(&n.Children[e], vState.X, vState.Y, tempStates[i].X, tempStates[i].Y, state)
vState.X = tempStates[i].X
(*state)[n.Children[e].Properties.Id] = vState
}
for i := 0; i < len(tempStates); i++ {
e := row[0] + i
n.Children[e] = tempNodes[i]
}
for i := row[1] - 1; i >= row[0]; i-- {
vState := s[n.Children[i].Properties.Id]
var xChng float32
if i < row[1]-1 {
sib := s[n.Children[i+1].Properties.Id]
xChng = sib.X - (sib.Border.Width + sib.Margin.Left + vState.Margin.Right + vState.Border.Width + vState.Width)
} else {
parent := s[n.Properties.Id]
xChng = ((((parent.X + parent.Width) - parent.Padding.Right) - vState.Width) - vState.Margin.Right) - (vState.Border.Width)
}
propagateOffsets(&n.Children[i], vState.X, vState.Y, xChng, vState.Y, state)
vState.X = xChng
(*state)[n.Children[i].Properties.Id] = vState
}
}
}
func justifyRow(rows [][]int, n *element.Node, state *map[string]element.State, justify string, reversed bool) {
s := *state
for _, row := range rows {
if (justify == "flex-end" || justify == "end" || justify == "right") && !reversed {
for i := row[1] - 1; i >= row[0]; i-- {
vState := s[n.Children[i].Properties.Id]
var xChng float32
if i < row[1]-1 {
sib := s[n.Children[i+1].Properties.Id]
xChng = sib.X - (sib.Border.Width + sib.Margin.Left + vState.Margin.Right + vState.Border.Width + vState.Width)
} else {
parent := s[n.Properties.Id]
xChng = ((((parent.X + parent.Width) - parent.Padding.Right) - vState.Width) - vState.Margin.Right) - (vState.Border.Width)
}
propagateOffsets(&n.Children[i], vState.X, vState.Y, xChng, vState.Y, state)
vState.X = xChng
(*state)[n.Children[i].Properties.Id] = vState
}
} else if (justify == "flex-end" || justify == "start" || justify == "left" || justify == "normal") && reversed {
for i := row[0]; i < row[1]; i++ {
vState := s[n.Children[i].Properties.Id]
var xChng float32
if i > row[0] {
sib := s[n.Children[i-1].Properties.Id]
xChng = sib.X + sib.Width + (sib.Border.Width * 2) + sib.Margin.Right + vState.Margin.Left + vState.Border.Width
} else {
parent := s[n.Properties.Id]
xChng = parent.X + parent.Padding.Right + vState.Margin.Left + vState.Border.Width + parent.Border.Width
}
propagateOffsets(&n.Children[i], vState.X, vState.Y, xChng, vState.Y, state)
vState.X = xChng
(*state)[n.Children[i].Properties.Id] = vState
}
} else if justify == "center" {
// get width of row then center (by getting last x + w + mr + b)
f := s[n.Children[row[0]].Properties.Id]
l := s[n.Children[row[1]-1].Properties.Id]
parent := s[n.Properties.Id]
po := parent.X + parent.Border.Width
offset := (parent.Width - ((f.X - po) + (l.X - po) + l.Width + f.Border.Width + l.Border.Width)) / 2
for i := row[0]; i < row[1]; i++ {
vState := s[n.Children[i].Properties.Id]
if !reversed {
propagateOffsets(&n.Children[i], vState.X, vState.Y, vState.X+offset, vState.Y, state)
vState.X += offset
} else {
propagateOffsets(&n.Children[i], vState.X, vState.Y, vState.X-offset, vState.Y, state)
vState.X -= offset
}
(*state)[n.Children[i].Properties.Id] = vState
}
} else if justify == "space-between" {
// get width of row then center (by getting last x + w + mr + b)
f := s[n.Children[row[0]].Properties.Id]
l := s[n.Children[row[1]-1].Properties.Id]
parent := s[n.Properties.Id]
po := parent.Border.Width + parent.Width
po -= parent.Padding.Left + parent.Padding.Right
// make po repersent the total space between elements
for i := row[0]; i < row[1]; i++ {
vState := s[n.Children[i].Properties.Id]
po -= vState.Width + vState.Margin.Left + vState.Margin.Right + (vState.Border.Width * 2)
}
po /= float32(((row[1]) - row[0]) - 1)
if (row[1]-1)-row[0] > 0 {
for i := row[0]; i < row[1]; i++ {
vState := s[n.Children[i].Properties.Id]
var offset float32
if i == row[0] {
offset = parent.X + parent.Padding.Left + f.Margin.Left + f.Border.Width
} else if i == row[1]-1 {
offset = (parent.X + parent.Width) - (l.Margin.Right + l.Border.Width + l.Width + parent.Padding.Right)
} else {
if !reversed {
offset = vState.X + (po * float32(i-row[0]))
} else {
offset = vState.X - (po * float32(((row[1]-1)-row[0])-(i-row[0])))
}
}
propagateOffsets(&n.Children[i], vState.X, vState.Y, offset, vState.Y, state)
vState.X = offset
(*state)[n.Children[i].Properties.Id] = vState
}
} else {
// if there is one element move left
vState := s[n.Children[(row[1]-1)-row[0]].Properties.Id]
var offset float32
if !reversed {
offset = parent.X + parent.Padding.Left + f.Margin.Left + f.Border.Width
propagateOffsets(&n.Children[(row[1]-1)-row[0]], vState.X, vState.Y, offset, vState.Y, state)
vState.X = offset
(*state)[n.Children[(row[1]-1)-row[0]].Properties.Id] = vState
}
}
} else if justify == "space-evenly" {
// get width of row then center (by getting last x + w + mr + b)
parent := s[n.Properties.Id]
po := parent.Border.Width + parent.Width
po -= parent.Padding.Left + parent.Padding.Right
// make po repersent the total space between elements
for i := row[0]; i < row[1]; i++ {
vState := s[n.Children[i].Properties.Id]
po -= vState.Width + vState.Margin.Left + vState.Margin.Right + (vState.Border.Width * 2)
}
po /= float32(((row[1]) - row[0]) + 1)
// get width of row then center (by getting last x + w + mr + b)
for i := row[0]; i < row[1]; i++ {
vState := s[n.Children[i].Properties.Id]
if !reversed {
offset := po * (float32(i-row[0]) + 1)
propagateOffsets(&n.Children[i], vState.X, vState.Y, vState.X+offset, vState.Y, state)
vState.X += offset
} else {
offset := po * float32(((row[1]-1)-row[0])-((i-row[0])-1))
propagateOffsets(&n.Children[i], vState.X, vState.Y, vState.X-offset, vState.Y, state)
vState.X -= offset
}
(*state)[n.Children[i].Properties.Id] = vState
}
} else if justify == "space-around" {
// get width of row then center (by getting last x + w + mr + b)
parent := s[n.Properties.Id]
po := parent.Border.Width + parent.Width
po -= parent.Padding.Left + parent.Padding.Right
// make po repersent the total space between elements
for i := row[0]; i < row[1]; i++ {
vState := s[n.Children[i].Properties.Id]
po -= vState.Width + vState.Margin.Left + vState.Margin.Right + (vState.Border.Width * 2)
}
po /= float32(((row[1]) - row[0]))
// get width of row then center (by getting last x + w + mr + b)
for i := row[0]; i < row[1]; i++ {
vState := s[n.Children[i].Properties.Id]
if !reversed {
m := (float32(i-row[0]) + 1)
if i-row[0] == 0 {
m = 0.5
} else {
m -= 0.5
}
offset := po * m
propagateOffsets(&n.Children[i], vState.X, vState.Y, vState.X+offset, vState.Y, state)
vState.X += offset
} else {
m := float32(((row[1] - 1) - row[0]) - ((i - row[0]) - 1))
m -= 0.5
offset := po * m
propagateOffsets(&n.Children[i], vState.X, vState.Y, vState.X-offset, vState.Y, state)
vState.X -= offset
}
(*state)[n.Children[i].Properties.Id] = vState
}
}
}
}
func alignItemsRow(rows [][]int, n *element.Node, state *map[string]element.State, align string) {
// needs
// baseline - top
// flex-start
// self-start
// start
// center - middle
// end - end
// flex-end
// self-end
props := []string{
"baseline",
"flex-start",
"self-start",
"start",
"center",
"end",
"flex-end",
"self-end",
}
matches := false
for _, v := range props {
if align == v {
matches = true
break
}
}
if !matches {
return
}
s := *state
self := s[n.Properties.Id]
maxes := []float32{}
var maxesTotal float32
for _, row := range rows {
var maxH float32
for i := row[0]; i < row[1]; i++ {
vState := s[n.Children[i].Properties.Id]
_, h := getInnerSize(&n.Children[i], state)
h = getMinHeight(n.Children[i], state, h)
vState.Height = h
h += vState.Margin.Top + vState.Margin.Bottom + (vState.Border.Width * 2)
maxH = utils.Max(maxH, h)
// this doesn't work, don't try again
// maxH -= vState.Border.Width
(*state)[n.Children[i].Properties.Id] = vState
}
maxes = append(maxes, maxH)
maxesTotal += maxH
}
os := ((self.Height - (self.Margin.Top + self.Margin.Bottom + (self.Border.Width * 2))) - maxesTotal) / float32(len(rows)+1)
for c, row := range rows {
maxH := maxes[c]
if align == "start" || align == "flex-start" || align == "self-start" {
for i := row[0]; i < row[1]; i++ {
vState := s[n.Children[i].Properties.Id]
offset := (vState.Y + (os * float32(c)) + vState.Margin.Top + vState.Border.Width)
propagateOffsets(&n.Children[i], vState.X, vState.Y, vState.X, offset, state)
vState.Y = offset
(*state)[n.Children[i].Properties.Id] = vState
}
} else if align == "center" {
for i := row[0]; i < row[1]; i++ {
vState := s[n.Children[i].Properties.Id]
offset := (vState.Y + (os*float32(c))/2)
if vState.Height+vState.Margin.Top+vState.Margin.Bottom+(vState.Border.Width*2) < maxH {
offset += (maxH - (vState.Height + vState.Margin.Top + vState.Border.Width)) / 2
} else {
offset += vState.Margin.Top + vState.Border.Width
}
propagateOffsets(&n.Children[i], vState.X, vState.Y, vState.X, offset, state)
vState.Y = offset
(*state)[n.Children[i].Properties.Id] = vState
}
} else if align == "end" || align == "flex-end" || align == "self-end" {
for i := row[0]; i < row[1]; i++ {
vState := s[n.Children[i].Properties.Id]
offset := ((vState.Y + (os * float32(c+1))) + (maxH - (vState.Height + vState.Margin.Top + vState.Border.Width)))
propagateOffsets(&n.Children[i], vState.X, vState.Y, vState.X, offset, state)
vState.Y = offset
(*state)[n.Children[i].Properties.Id] = vState
}
}
}
}