CrabUI
Loading...
Searching...
No Matches
CUIComponent.cs
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Reflection;
5using System.Diagnostics;
6using System.Runtime.CompilerServices;
7using System.IO;
8
9using Barotrauma;
10using Microsoft.Xna.Framework;
11using Microsoft.Xna.Framework.Input;
12using Microsoft.Xna.Framework.Graphics;
13
14using System.Xml;
15using System.Xml.Linq;
16using HarmonyLib;
17using System.Threading;
18
19namespace CrabUI
20{
21 /// <summary>
22 /// Base class for all components
23 /// </summary>
24 public partial class CUIComponent : ICUIComponent, IDisposable
25 {
26 #region Static --------------------------------------------------------
27 internal static void InitStatic()
28 {
29 CUI.OnInit += () =>
30 {
31 MaxID = 0;
32 };
33
34 CUI.OnDispose += () =>
35 {
36 foreach (int id in ComponentsById.Keys)
37 {
38 CUIComponent component = null;
39 ComponentsById[id].TryGetTarget(out component);
40 component?.Dispose();
41 }
42
43 ComponentsById.Clear();
44 ComponentsByType.Clear();
45
46
47 dummyComponent = null;
48 };
49 }
50
51 internal static int MaxID;
52 public static Dictionary<int, WeakReference<CUIComponent>> ComponentsById = new();
53 public static IEnumerable<CUIComponent> AllComponents => ComponentsById.Values
54 .Select(wr =>
55 {
56 CUIComponent component = null;
57 wr.TryGetTarget(out component);
58 return component;
59 })
60 .Where(c => c != null);
61 public static WeakCatalog<Type, CUIComponent> ComponentsByType = new();
62
63 /// <summary>
64 /// This is used to trick vanilla GUI into believing that
65 /// mouse is hovering some component and block clicks
66 /// </summary>
67 public static GUIButton dummyComponent = new GUIButton(new RectTransform(new Point(0, 0)))
68 {
69 Text = "DUMMY",
70 };
71 /// <summary>
72 /// designed to be versatile, in fact never used
73 /// </summary>
74 public static void RunRecursiveOn(CUIComponent component, Action<CUIComponent> action)
75 {
76 action(component);
77 foreach (CUIComponent child in component.Children)
78 {
79 RunRecursiveOn(child, action);
80 }
81 }
82
83
84 public static void ForEach(Action<CUIComponent> action)
85 {
86 foreach (int id in ComponentsById.Keys)
87 {
88 CUIComponent component = null;
89 ComponentsById[id].TryGetTarget(out component);
90 if (component is not null) action(component);
91 }
92 }
93
94 public static IEnumerable<Type> GetClassHierarchy(Type type)
95 {
96 while (type != typeof(Object) && type != null)
97 {
98 yield return type;
99 type = type.BaseType;
100 }
101 }
102
103 public static IEnumerable<Type> GetReverseClassHierarchy(Type type)
104 => CUIComponent.GetClassHierarchy(type).Reverse<Type>();
105
106 #endregion
107 #region Virtual --------------------------------------------------------
108
109
110 //TODO move to cui props, it's a bit more clampicated than ChildrenBoundaries
111 /// <summary>
112 /// Bounds for offset, e.g. scroll, zoom
113 /// </summary>
114 internal virtual CUIBoundaries ChildOffsetBounds => new CUIBoundaries();
115 /// <summary>
116 /// "Component like" ghost stuff that can't have children and
117 /// doesn't impact layout. Drag handles, text etc
118 /// </summary>
119 internal virtual void UpdatePseudoChildren()
120 {
121 LeftResizeHandle.Update();
122 RightResizeHandle.Update();
123 }
124 /// <summary>
125 /// Last chance to disagree with proposed size
126 /// For stuff that should resize to content
127 /// </summary>
128 /// <param name="size"> proposed size </param>
129 /// <returns> size you're ok with </returns>
130 internal virtual Vector2 AmIOkWithThisSize(Vector2 size) => size;
131 /// <summary>
132 /// Here component should be drawn
133 /// </summary>
134 /// <param name="spriteBatch"></param>
135 public virtual partial void Draw(SpriteBatch spriteBatch);
136 /// <summary>
137 /// Method for drawing something that should always be on top, e.g. resize handles
138 /// </summary>
139 /// <param name="spriteBatch"></param>
140 public virtual partial void DrawFront(SpriteBatch spriteBatch);
141
142 #endregion
143 #region Draw --------------------------------------------------------
144
145 public virtual partial void Draw(SpriteBatch spriteBatch)
146 {
147 if (BackgroundVisible) CUI.DrawRectangle(spriteBatch, Real, BackgroundColor * Transparency, BackgroundSprite);
148
149 CUI.DrawBorders(spriteBatch, this);
150 // if (Border.Visible) GUI.DrawRectangle(spriteBatch, BorderBox.Position, BorderBox.Size, Border.Color, thickness: Border.Thickness);
151
152 if (OutlineVisible) GUI.DrawRectangle(spriteBatch, OutlineBox.Position, OutlineBox.Size, OutlineColor, thickness: OutlineThickness);
153 }
154
155 public virtual partial void DrawFront(SpriteBatch spriteBatch)
156 {
157 LeftResizeHandle.Draw(spriteBatch);
158 RightResizeHandle.Draw(spriteBatch);
159
160 if (DebugHighlight)
161 {
162 CUI.DrawTexture(spriteBatch, Real, CUITextureManager.Checkers, Color.White * 0.5f, CUISpriteDrawMode.Static);
163 }
164 }
165
166
167 #endregion
168 #region Constructors --------------------------------------------------------
169
170
171 internal void Vitalize()
172 {
173 foreach (FieldInfo fi in this.GetType().GetFields(AccessTools.all))
174 {
175 if (fi.FieldType.IsAssignableTo(typeof(ICUIVitalizable)))
176 {
177 ICUIVitalizable prop = (ICUIVitalizable)fi.GetValue(this);
178 if (prop == null) continue;
179 prop.SetHost(this);
180 }
181 }
182 }
183 internal void VitalizeProps()
184 {
185 foreach (FieldInfo fi in this.GetType().GetFields(AccessTools.all))
186 {
187 if (fi.FieldType.IsAssignableTo(typeof(ICUIProp)))
188 {
189 ICUIProp prop = (ICUIProp)fi.GetValue(this);
190 if (prop == null) continue; // this is for Main.GrabbedDragHandle
191 prop.SetHost(this);
192 prop.SetName(fi.Name);
193 }
194 }
195
196 foreach (FieldInfo fi in typeof(CUIComponentProps).GetFields(AccessTools.all))
197 {
198 if (fi.FieldType.IsAssignableTo(typeof(ICUIProp)))
199 {
200 ICUIProp prop = (ICUIProp)fi.GetValue(CUIProps);
201 if (prop == null) continue;
202 prop.SetHost(this);
203 prop.SetName(fi.Name);
204 }
205 }
206 }
207
208 public CUIComponent()
209 {
210 if (CUI.Disposed)
211 {
212 Disposed = true;
213 return;
214 }
215
216 ID = MaxID++;
217
218 ComponentsById[ID] = new WeakReference<CUIComponent>(this);
219 ComponentsByType.Add(this.GetType(), this);
220
221 Vitalize();
222 VitalizeProps();
223
224 SetupCommands();
225
226 Layout = new CUILayoutSimple();
227
228 SetupStyles();
229 SetupAnimations();
230 }
231
232 public CUIComponent(float? x = null, float? y = null, float? w = null, float? h = null) : this()
233 {
234 Relative = new CUINullRect(x, y, w, h);
235 }
236
237 public bool Disposed;
238 public void Dispose()
239 {
240 if (Disposed) return;
241 CleanUp();
242 Disposed = true;
243 }
244 public virtual void CleanUp() { }
245
246 ~CUIComponent() => Dispose();
247
248 public override string ToString() => $"{this.GetType().Name}:{ID}:{AKA}";
249 #endregion
250 }
251}
Base class for all components.
CUINullRect Relative
Relative to parent size and position, [0..1].
virtual partial void DrawFront(SpriteBatch spriteBatch)
Method for drawing something that should always be on top, e.g. resize handles.
CUIComponentProps CUIProps
Just a wrapper for CUIProps idk how to separate them better.
Definition CUIProps.cs:27
bool BackgroundVisible
BackgroundColor != Color.Transparent.
Color BackgroundColor
Color of BackgroundSprite, default is black If you're using custom sprite and don't see it make sur...
CUIRect Real
Calculated prop, position on real screen in pixels Should be fully calculated after CUIMainComponent....
virtual partial void Draw(SpriteBatch spriteBatch)
Here component should be drawn.
int ID
Global ID, unique for component.
static GUIButton dummyComponent
This is used to trick vanilla GUI into believing that mouse is hovering some component and block clic...
Color OutlineColor
Outline is like a border, but on the outside of the component.
static void RunRecursiveOn(CUIComponent component, Action< CUIComponent > action)
designed to be versatile, in fact never used
CUISprite BackgroundSprite
Will be drawn in background with BackgroundColor Default is solid white 1x1 texture.
In fact a static class managing static things.
Definition CUIErrors.cs:16
Class for loading textures without duplicates Also disposes all loaded textures automatically.
static Texture2D Checkers
Path to additional PNGs, it can be set in CUI.