1using System.Numerics;
2using System.Reflection;
3using Fjord.Input;
4using Fjord.Ui;
5using Fjord.Graphics;
6using static SDL2.SDL;
7
8namespace Fjord.Scenes;
9
10public class InspectorScene : Scene
11{
12 float yOffset = 0;
13
14 public string SelectedScene {
15 get;
16 internal set;
17 } = "";
18
19 public void SetSelectedScene<T>()
20 {
21 SelectedScene = typeof(T).Name;
22 }
23
24 public InspectorScene(int width, int height) : base(width, height)
25 {
26 ClearColor = UiStyles.Background;
27 // SetUpdateOnlyIfActive(true);
28 }
29
30 public override void Update()
31 {
32 if(SelectedScene == "")
33 {
34 SelectedScene = SceneHandler.Scenes.First(e => e.Key != "InspectorScene" && e.Key != "ConsoleScene" && e.Key != "PerformanceScene").Key;
35 }
36
37 if(MouseInsideScene)
38 {
39 if(Mouse.Pressed(MB.ScrollDown)) {
40 yOffset -= 10;
41 }
42 if(Mouse.Pressed(MB.ScrollUp)) {
43 yOffset += 10;
44 }
45 }
46
47 new UiBuilder(new Vector4(0, yOffset, (int)(Game.Window.Width * 0.2), (int)Game.Window.Height), Mouse.Position)
48 .Title($"Inspector for {SelectedScene}")
49 .If(SceneHandler.Get(SelectedScene).Paused, new UiButton("Resume", () => SceneHandler.Get(SelectedScene).Paused = false))
50 .If(!SceneHandler.Get(SelectedScene).Paused, new UiButton("Pause", () => SceneHandler.Get(SelectedScene).Paused = true))
51 .ForEach(SceneHandler.Get(SelectedScene).Entities, (e) => {
52 if(e.excludeFromInspector)
53 {
54 return null;
55 }
56
57 return new UiBuilder()
58 .Title(e.name == null ? e.ToString()! : e.name)
59 .ForEach(e.Components, (c) => {
60 var list = new UiBuilder()
61 .Title(c.ToString()!)
62 .Build();
63
64 FieldInfo[] infos = c.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
65
66 List<object> exports = new() {
67
68 };
69
70 foreach(var fi in infos) {
71 if (fi.IsDefined(typeof(Export), true))
72 {
73 var fival = fi.GetValue(c);
74 if(fival is not null)
75 {
76 exports.Add(new UiText(fi.Name));
77 if (fival.GetType() == typeof(string))
78 {
79 exports.Add(new UiTextField(fi.Name, fival.ToString()!, (result) =>
80 {
81 fi.SetValue(c, result);
82 }, (result) => { }));
83 }
84 else if (fival.GetType() == typeof(bool))
85 {
86 exports.RemoveAt(exports.Count - 1);
87 exports.Add(new UiCheckbox(fi.Name, (bool)fival, () =>
88 {
89 fi.SetValue(c, !(bool)fival);
90 }));
91 }
92 else if (fival.GetType() == typeof(float))
93 {
94 exports.RemoveAt(exports.Count - 1);
95 exports.Add(new UiText($"{fi.Name} ({(float)fival})"));
96 var expor = fi.GetCustomAttribute(typeof(Export));
97 if (expor is not null)
98 {
99 Export a = (Export)expor;
100
101 exports.Add(new UiSlider(a.sliderMin, a.sliderMax, (float)fival, (result) =>
102 {
103 fi.SetValue(c, result);
104 }));
105 }
106 } else if(fival.GetType() == typeof(int)) {
107 exports.RemoveAt(exports.Count - 1);
108 exports.Add(new UiText($"{fi.Name} ({(int)fival})"));
109 var expor = fi.GetCustomAttribute(typeof(Export));
110 if (expor is not null)
111 {
112 Export a = (Export)expor;
113
114 exports.Add(new UiSlider(a.sliderMin, a.sliderMax, (int)fival, (result) => {
115 fi.SetValue(c, (int)result);
116 }));
117 }
118 } else if(fival.GetType() == typeof(Vector2))
119 {
120 exports.RemoveAt(exports.Count - 1);
121 exports.Add(new UiText($"{fi.Name}"));
122 var expor = fi.GetCustomAttribute(typeof(Export));
123 if (expor is not null)
124 {
125 Export a = (Export)expor;
126
127 exports.Add(new HAlign<UiComponent>() {
128 new UiSlider(a.sliderMin, a.sliderMax, ((Vector2)fival).X, (result) => {
129 fi.SetValue(c, new Vector2(result, ((Vector2)fival).Y));
130 }),
131 new UiTitle("X")
132 });
133
134 exports.Add(new HAlign<UiComponent>() {
135 new UiSlider(a.sliderMin, a.sliderMax, ((Vector2)fival).Y, (result) => {
136 fi.SetValue(c, new Vector2(((Vector2)fival).X, result));
137 }),
138 new UiTitle("Y")
139 });
140 }
141 } else {
142 exports.RemoveAt(exports.Count - 1);
143 exports.Add(new UiText($"{fi.Name} has an unsupported type: {fival.GetType()}!"));
144 }
145 }
146 }
147 }
148
149 if (exports.Count > 0)
150 {
151 list.AddRange(exports);
152 return list;
153 }
154
155 return null;
156 })
157 .Build();
158 })
159 .Render(out int uiHeight);
160
161 if(MouseInsideScene)
162 {
163 if(uiHeight > WindowSize.Y) {
164 if(-yOffset < 0) {
165 yOffset = 0;
166 }
167 if(-yOffset > uiHeight - WindowSize.Y + 50) {
168 yOffset = -uiHeight + WindowSize.Y - 50;
169 }
170 } else {
171 yOffset = 0;
172 }
173 }
174 }
175}
176
177