Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
ListPanelWidget.cs
浏览该文件的文档.
1using Engine;
3
4namespace Game {
6 public List<object> m_items = [];
7
8 public int? m_selectedItemIndex;
9
10 public Dictionary<int, Widget> m_widgetsByIndex = [];
11
13
15
16 public bool PlayClickSound = true;
17
18 public float m_itemSize;
19
20 public bool m_widgetsDirty;
21
22 public bool m_clickAllowed;
23
24 public Vector2 lastActualSize = new(-1f);
25
26 public Func<object, Widget> ItemWidgetFactory { get; set; }
27
28 public override LayoutDirection Direction {
29 get => base.Direction;
30 set {
31 if (value != Direction) {
32 base.Direction = value;
33 m_widgetsDirty = true;
34 }
35 }
36 }
37
38 public override float ScrollPosition {
39 get => base.ScrollPosition;
40 set {
41 if (value != ScrollPosition) {
42 base.ScrollPosition = value;
43 m_widgetsDirty = true;
44 }
45 }
46 }
47
48 public float ItemSize {
49 get => m_itemSize;
50 set {
51 if (value != m_itemSize) {
52 m_itemSize = value;
53 m_widgetsDirty = true;
54 }
55 }
56 }
57
58 public int? SelectedIndex {
60 set {
61 if (value.HasValue
62 && (value.Value < 0 || value.Value >= m_items.Count)) {
63 value = null;
64 }
65 if (value != m_selectedItemIndex) {
66 m_selectedItemIndex = value;
67 SelectionChanged?.Invoke();
68 }
69 }
70 }
71
72 public object SelectedItem {
73 get {
74 if (!m_selectedItemIndex.HasValue) {
75 return null;
76 }
77 return m_items[m_selectedItemIndex.Value];
78 }
79 set {
80 int num = m_items.IndexOf(value);
81 SelectedIndex = num >= 0 ? new int?(num) : null;
82 }
83 }
84
85 public ReadOnlyList<object> Items => new(m_items);
86
87 public Color SelectionColor { get; set; }
88
89 public virtual Action<object> ItemClicked { get; set; }
90
91 public virtual Action SelectionChanged { get; set; }
92
93 public ListPanelWidget() {
95 ItemWidgetFactory = item => new LabelWidget {
96 Text = item != null ? item.ToString() : string.Empty,
99 };
100 ItemSize = 48f;
101 }
102
103 public void AddItem(object item) {
104 m_items.Add(item);
105 m_widgetsDirty = true;
106 }
107
108 public void AddItems(IEnumerable<object> items) {
109 m_items.AddRange(items);
110 m_widgetsDirty = true;
111 }
112
113 public void RemoveItem(object item) {
114 int num = m_items.IndexOf(item);
115 if (num >= 0) {
116 RemoveItemAt(num);
117 }
118 }
119
120 public void RemoveItemAt(int index) {
121 _ = m_items[index];
122 m_items.RemoveAt(index);
123 m_widgetsByIndex.Clear();
124 m_widgetsDirty = true;
125 if (index == SelectedIndex) {
126 SelectedIndex = null;
127 }
128 }
129
130 public void ClearItems() {
131 m_items.Clear();
132 m_widgetsByIndex.Clear();
133 m_widgetsDirty = true;
134 SelectedIndex = null;
135 }
136
137 public override float CalculateScrollAreaLength() => Items.Count * ItemSize;
138
139 public void ScrollToItem(object item) {
140 int num = m_items.IndexOf(item);
141 if (num >= 0) {
142 float num2 = num * ItemSize;
143 float num3 = Direction == LayoutDirection.Horizontal ? ActualSize.X : ActualSize.Y;
144 if (num2 < ScrollPosition) {
145 ScrollPosition = num2;
146 }
147 else if (num2 > ScrollPosition + num3 - ItemSize) {
148 ScrollPosition = num2 - num3 + ItemSize;
149 }
150 }
151 }
152
153 public override void MeasureOverride(Vector2 parentAvailableSize) {
154 IsDrawRequired = true;
155 foreach (Widget child in Children) {
156 if (child.IsVisible) {
157 if (Direction == LayoutDirection.Horizontal) {
158 child.Measure(new Vector2(ItemSize, MathUtils.Max(parentAvailableSize.Y - child.MarginVerticalSum, 0f)));
159 }
160 else {
161 child.Measure(new Vector2(MathUtils.Max(parentAvailableSize.X - child.MarginHorizontalSum, 0f), ItemSize));
162 }
163 }
164 }
165 if (m_widgetsDirty) {
166 m_widgetsDirty = false;
168 }
169 }
170
171 public override void ArrangeOverride() {
172 if (ActualSize != lastActualSize) {
173 m_widgetsDirty = true;
174 }
176 int num = m_firstVisibleIndex;
177 foreach (Widget child in Children) {
178 if (Direction == LayoutDirection.Horizontal) {
179 Vector2 vector = new(num * ItemSize - ScrollPosition, 0f);
180 ArrangeChildWidgetInCell(vector, vector + new Vector2(ItemSize, ActualSize.Y), child);
181 }
182 else {
183 Vector2 vector2 = new(0f, num * ItemSize - ScrollPosition);
184 ArrangeChildWidgetInCell(vector2, vector2 + new Vector2(ActualSize.X, ItemSize), child);
185 }
186 num++;
187 }
188 }
189
190 public override void Update() {
191 bool flag = ScrollSpeed != 0f;
192 base.Update();
193 if (Input.Tap.HasValue
194 && HitTestPanel(Input.Tap.Value)) {
195 m_clickAllowed = !flag;
196 }
197 if (Input.Click.HasValue
199 && HitTestPanel(Input.Click.Value.Start)
200 && HitTestPanel(Input.Click.Value.End)) {
201 int num = PositionToItemIndex(Input.Click.Value.End);
202 if (ItemClicked != null
203 && num >= 0
204 && num < m_items.Count) {
205 ItemClicked(Items[num]);
206 }
207 SelectedIndex = num;
208 if (SelectedIndex.HasValue && PlayClickSound) {
209 AudioManager.PlaySound("Audio/UI/ButtonClick", 1f, 0f, 0f);
210 }
211 }
212 }
213
214 public override void Draw(DrawContext dc) {
215 if (SelectedIndex.HasValue
217 && SelectedIndex.Value <= m_lastVisibleIndex) {
219 ? new Vector2(SelectedIndex.Value * ItemSize - ScrollPosition, 0f)
220 : new Vector2(0f, SelectedIndex.Value * ItemSize - ScrollPosition);
222 int count = flatBatch2D.TriangleVertices.Count;
224 flatBatch2D.QueueQuad(vector, vector + v, 0f, SelectionColor * GlobalColorTransform);
225 flatBatch2D.TransformTriangles(GlobalTransform, count);
226 }
227 base.Draw(dc);
228 }
229
230 public int PositionToItemIndex(Vector2 position) {
231 Vector2 vector = ScreenToWidget(position);
232 if (Direction == LayoutDirection.Horizontal) {
233 return (int)((vector.X + ScrollPosition) / ItemSize);
234 }
235 return (int)((vector.Y + ScrollPosition) / ItemSize);
236 }
237
238 public void CreateListWidgets(float size) {
239 Children.Clear();
240 if (m_items.Count <= 0) {
241 return;
242 }
243 int x = (int)MathF.Floor(ScrollPosition / ItemSize);
244 int x2 = (int)MathF.Floor((ScrollPosition + size) / ItemSize);
246 m_lastVisibleIndex = MathUtils.Min(x2, m_items.Count - 1);
247 for (int i = m_firstVisibleIndex; i <= m_lastVisibleIndex; i++) {
248 object obj = m_items[i];
249 if (!m_widgetsByIndex.TryGetValue(i, out Widget value)) {
250 value = ItemWidgetFactory(obj);
251 value.Tag = obj;
252 m_widgetsByIndex.Add(i, value);
253 }
254 Children.Add(value);
255 }
256 }
257 }
258}
readonly DynamicArray< VertexPositionColor > TriangleVertices
void TransformTriangles(Matrix matrix, int start=0, int end=-1)
static readonly DepthStencilState None
void QueueQuad(Vector2 corner1, Vector2 corner2, float depth, Color color)
FlatBatch2D FlatBatch(int layer=0, DepthStencilState depthStencilState=null, RasterizerState rasterizerState=null, BlendState blendState=null)
static int Min(int x1, int x2)
static int Max(int x1, int x2)
static void PlaySound(string name, float volume, float pitch, float pan)
readonly WidgetsList Children
static void ArrangeChildWidgetInCell(Vector2 c1, Vector2 c2, Widget widget)
ReadOnlyList< object > Items
void CreateListWidgets(float size)
override void MeasureOverride(Vector2 parentAvailableSize)
Dictionary< int, Widget > m_widgetsByIndex
int PositionToItemIndex(Vector2 position)
override void Draw(DrawContext dc)
override float CalculateScrollAreaLength()
void ScrollToItem(object item)
override LayoutDirection Direction
Func< object, Widget > ItemWidgetFactory
void AddItems(IEnumerable< object > items)
virtual Action< object > ItemClicked
bool HitTestPanel(Vector2 position)
readonly PrimitivesRenderer2D PrimitivesRenderer2D
virtual float MarginVerticalSum
virtual bool IsVisible
virtual float MarginHorizontalSum
WidgetInput Input
Color GlobalColorTransform
virtual WidgetAlignment VerticalAlignment
virtual WidgetAlignment HorizontalAlignment
bool IsDrawRequired
Vector2 ActualSize
virtual Vector2 ScreenToWidget(Vector2 p)
Matrix GlobalTransform
virtual void Measure(Vector2 parentAvailableSize)
static Color Gray