summaryrefslogtreecommitdiff
path: root/engine/Dynamic/Descriptors/UIElement.go
blob: da523e99d2e6a182df656632a728eb1be905a89c (plain)
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package descriptors

import (
	"fmt"
	"strings"

	components "github.com/DegustatorPonos/RuinesOfRafdolon/Components"
	ui "github.com/DegustatorPonos/RuinesOfRafdolon/UI"
	rl "github.com/gen2brain/raylib-go/raylib"
)

type UIElementDescriptor struct {
	Type string
	Weight float32
	Style StyleDescriptor

	// For labels
	Text string
	Alignment string

	// For grid elements
	Children []UIElementDescriptor
	Spacing float32

	// For images
	TextureName string
}

// We have to initialize the map so that we avoid the circular reference in the recursive parsing
func InitUIParser() {
	typeParsers = map[string]func(*UIElementDescriptor) ui.UIElement {
		ui.VoidTypeName: parseAsVoid,
		ui.LabelTypeName: parseAsLabel,
		ui.ImageTypeName: parseAsImage,
		ui.GridRowTypeName: parseAsGridRow,
		ui.GridColumnTypeName: parseAsGridColumn,
	}
}

// The item type to its parser relationship
var typeParsers map[string]func(*UIElementDescriptor) ui.UIElement

func (base *UIElementDescriptor) Parse() (ui.UIElement, error) {
	var elemType = strings.ToLower(base.Type)
	var descFunc, exists = typeParsers[elemType]
	if exists {
		return descFunc(base), nil
	}
	return nil, fmt.Errorf("Unknown UI element type")
}

func parseAsVoid(base *UIElementDescriptor) ui.UIElement {
	return &ui.Void {
		Weight: base.Weight,
	}
}

func parseAsLabel(base *UIElementDescriptor) ui.UIElement {
	var alignment ui.TextAlignment
	switch strings.ToLower(base.Alignment) {
	case "center":
		alignment = ui.Center
	case "start":
		alignment = ui.Start
	}

	return &ui.Label {
		Weight: base.Weight,
		Text: base.Text,
		Alignment: alignment,
		Style: base.Style.Parse(),
	}
}

func parseAsGridRow(base *UIElementDescriptor) ui.UIElement {
	var outp = ui.GridRow {
		Weight: base.Weight,
		Spacing: base.Spacing,
		Style: base.Style.Parse(),
		Objects: make([]ui.UIElement, 0, len(base.Children)),
	}
	for _, v := range base.Children {
		var child, parseErr = v.Parse()
		if parseErr != nil {
			rl.TraceLog(rl.LogWarning, "Failed to parse a parent element of a grid row: %v", parseErr.Error())
			continue
		}
		outp.Objects = append(outp.Objects, child)
	}
	return &outp
}

func parseAsGridColumn(base *UIElementDescriptor) ui.UIElement {
	var outp = ui.GridColumn {
		Weight: base.Weight,
		Spacing: base.Spacing,
		Style: base.Style.Parse(),
		Objects: make([]ui.UIElement, 0, len(base.Children)),
	}
	for _, v := range base.Children {
		var child, parseErr = v.Parse()
		if parseErr != nil {
			rl.TraceLog(rl.LogWarning, "Failed to parse a parent element of a grid column: %v", parseErr.Error())
			continue
		}
		outp.Objects = append(outp.Objects, child)
	}
	return &outp
}

func parseAsImage(base *UIElementDescriptor) ui.UIElement {
	var texture, err = components.Resources.Textures.GetTextureByName(base.TextureName)
	if err != nil {
		rl.TraceLog(rl.LogWarning, "Failed to parse a texture %s requested by an inage UI element: %v", base.TextureName, err.Error())
		return nil
	}
	var outp = ui.Image {
		Weight: base.Weight,
		Texture: texture,
		Style: base.Style.Parse(),
	}
	return &outp
}