CrabUI
Loading...
Searching...
No Matches
CUIMap.cs
1using System;
2using System.Collections.Generic;
3using System.Linq;
4
5using Barotrauma;
6using Microsoft.Xna.Framework;
7using Microsoft.Xna.Framework.Input;
8using Microsoft.Xna.Framework.Graphics;
9using System.Xml;
10using System.Xml.Linq;
11namespace CrabUI
12{
13 /// <summary>
14 /// Swipable and zoomable plane
15 /// Allows you to place components in a plane
16 /// and connect them with lines like a graph or scheme
17 /// </summary>
18 public class CUIMap : CUIComponent
19 {
20 #region CUIMapLink
21 #endregion
22 public class CUIMapLink
23 {
24 internal static void InitStatic()
25 {
26 CUI.OnInit += () => Default = new CUIMapLink(null, null);
27 CUI.OnDispose += () => Default = null;
28 }
29 public static CUIMapLink Default;
30
31 public CUIComponent Start;
32 public CUIComponent End;
33
34 //TODO all this crap wasn't designed for nested AKA
35 public string StartAKA;
36 public string EndAKA;
37 public float LineWidth;
38 public Color LineColor;
39
40 public XElement ToXML()
41 {
42 XElement connection = new XElement("Connection");
43 if (LineWidth != Default.LineWidth)
44 {
45 connection.SetAttributeValue("LineWidth", LineWidth);
46 }
47 connection.SetAttributeValue("Start", StartAKA ?? "");
48 connection.SetAttributeValue("End", EndAKA ?? "");
49
50 return connection;
51 }
52
53 public CUIMapLink(CUIComponent start, CUIComponent end, Color? lineColor = null, float lineWidth = 2f)
54 {
55 LineColor = lineColor ?? new Color(128, 128, 128);
56 LineWidth = lineWidth;
57 Start = start;
58 End = end;
59
60 StartAKA = start?.AKA;
61 EndAKA = end?.AKA;
62 }
63 }
64
65 #region LinksContainer
66 #endregion
67 public class LinksContainer : CUIComponent
68 {
69 public List<CUIMapLink> Connections = new List<CUIMapLink>();
70
71 public override void Draw(SpriteBatch spriteBatch)
72 {
73 base.Draw(spriteBatch);
74
75 foreach (CUIMapLink link in Connections)
76 {
77 Vector2 midPoint = new Vector2(link.End.Real.Center.X, link.Start.Real.Center.Y);
78
79 GUI.DrawLine(spriteBatch,
80 link.Start.Real.Center,
81 midPoint,
82 link.LineColor, width: link.LineWidth
83 );
84
85 GUI.DrawLine(spriteBatch,
86 midPoint,
87 link.End.Real.Center,
88 link.LineColor, width: link.LineWidth
89 );
90 }
91 }
92
93 public LinksContainer()
94 {
95 UnCullable = true;
96 BackgroundColor = Color.Transparent;
97 Border.Color = Color.Transparent;
98 }
99 }
100
101 #region CUIMap
102 #endregion
103
104 public LinksContainer linksContainer;
105 public List<CUIMapLink> Connections => linksContainer.Connections;
106
107 public CUIComponent Add(CUIComponent c) => Append(c, c.AKA);
108
109
110
111 public CUIComponent Connect(CUIComponent startComponent, CUIComponent endComponent, Color? color = null)
112 {
113 if (startComponent != null && endComponent != null)
114 {
115 if (color == null && (!startComponent.Disabled || !endComponent.Disabled)) color = new Color(0, 0, 255);
116 linksContainer.Connections.Add(new CUIMapLink(startComponent, endComponent, color));
117 }
118 return startComponent;
119 }
120 public CUIComponent Connect(CUIComponent startComponent, int end = -2, Color? color = null)
121 {
122 end = MathUtils.PositiveModulo(end, Children.Count);
123 CUIComponent endComponent = Children.ElementAtOrDefault(end);
124 return Connect(startComponent, endComponent, color);
125 }
126
127 //TODO DRY
128 public CUIComponent Connect(string start, string end, Color? color = null)
129 {
130 CUIComponent startComponent = this[start];
131 CUIComponent endComponent = this[end];
132
133 if (startComponent != null && endComponent != null)
134 {
135 if (color == null && (!startComponent.Disabled || !endComponent.Disabled)) color = new Color(0, 0, 255);
136 linksContainer.Connections.Add(new CUIMapLink(startComponent, endComponent, color)
137 {
138 StartAKA = start,
139 EndAKA = end,
140 });
141 }
142 return startComponent;
143 }
144 public CUIComponent Connect(int start, int end, Color? color = null)
145 {
146 start = MathUtils.PositiveModulo(start, Children.Count);
147 end = MathUtils.PositiveModulo(end, Children.Count);
148
149 CUIComponent startComponent = Children.ElementAtOrDefault(start);
150 CUIComponent endComponent = Children.ElementAtOrDefault(end);
151 return Connect(startComponent, endComponent, color);
152 }
153
154 public CUIComponent ConnectTo(CUIComponent Host, params CUIComponent[] children)
155 {
156 foreach (CUIComponent child in children) { Connect(Host, child); }
157 return Host;
158 }
159
160
161 public override XElement ToXML(CUIAttribute propAttribute = CUIAttribute.CUISerializable)
162 {
163 Type type = GetType();
164
165 XElement element = new XElement(type.Name);
166
167 PackProps(element, propAttribute);
168
169 XElement connections = new XElement("Connections");
170 element.Add(connections);
171
172 foreach (CUIMapLink link in Connections)
173 {
174 connections.Add(link.ToXML());
175 }
176
177 XElement children = new XElement("Children");
178 element.Add(children);
179
180 foreach (CUIComponent child in Children)
181 {
182 if (child == linksContainer) continue;
183 children.Add(child.ToXML());
184 }
185
186 return element;
187 }
188
189
190 public override void FromXML(XElement element, string baseFolder = null)
191 {
192 foreach (XElement childElement in element.Element("Children").Elements())
193 {
194 Type childType = CUIReflection.GetComponentTypeByName(childElement.Name.ToString());
195 if (childType == null) continue;
196
197 CUIComponent child = (CUIComponent)Activator.CreateInstance(childType);
198 child.FromXML(childElement);
199
200 this.Append(child, child.AKA);
201 }
202
203 foreach (XElement link in element.Element("Connections").Elements())
204 {
205 CUIComponent startComponent = this[link.Attribute("Start").Value];
206 CUIComponent endComponent = this[link.Attribute("End").Value];
207
208 if (startComponent == null || endComponent == null)
209 {
210 CUIDebug.Error("startComponent == null || endComponent == null");
211 continue;
212 }
213 Connect(link.Attribute("Start").Value, link.Attribute("End").Value);
214 }
215
216 //TODO: think, this is potentially very bugged,
217 // Some props might need to be assigned before children, and some after
218 ExtractProps(element);
219 }
220
221 public CUIMap() : base()
222 {
223 Swipeable = true;
224 ConsumeMouseClicks = true;
225 CullChildren = true;
226 BackgroundColor = Color.Transparent;
227
228 //without container links won't be culled
229 //TODO linksContainer should be special and not just first child
230 this["links"] = linksContainer = new LinksContainer();
231
232 OnScroll += (m) =>
233 {
234 CUIProps.ChildrenOffset.SetValue(
235 ChildrenOffset.Zoom(
236 m.MousePosition - Real.Position,
237 (-m.Scroll / 500f)
238 )
239 );
240 };
241 }
242 }
243
244}
Base class for all components.
virtual bool Disabled
Usually means - non interactable, e.g. unclickable gray button.
CUI3DOffset ChildrenOffset
Will shift all children by this much, e.g. this is how scroll works It's also 3D.
CUIComponentProps CUIProps
Just a wrapper for CUIProps idk how to separate them better.
Definition CUIProps.cs:27
virtual CUIComponent Append(CUIComponent child, string name=null, [CallerMemberName] string memberName="")
Adds children to the end of the list.
string AKA
Parent can memorize it's children by their names, AKA.
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....
bool UnCullable
It shouldn't be culled off even outside of parent bounds and even if parent demands so.
bool CullChildren
if child rect doesn't intersect with parent it won't be drawn and won't consume fps It also sets Hi...
Swipable and zoomable plane Allows you to place components in a plane and connect them with lines l...
Definition CUIMap.cs:19