com.wallstop-studios.unity-helpers 2.0.0-rc73.2 → 2.0.0-rc73.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/Runtime/Tags/AttributeEffect.cs +1 -0
  2. package/Styles/Elements/Progress/ArcedProgressBar.cs +345 -0
  3. package/Styles/Elements/Progress/ArcedProgressBar.cs.meta +3 -0
  4. package/Styles/Elements/{CircularProgressBar.cs → Progress/CircularProgressBar.cs} +56 -55
  5. package/Styles/Elements/Progress/GlitchProgressBar.cs +416 -0
  6. package/Styles/Elements/Progress/GlitchProgressBar.cs.meta +3 -0
  7. package/Styles/Elements/Progress/LiquidProgressBar.cs +632 -0
  8. package/Styles/Elements/Progress/LiquidProgressBar.cs.meta +3 -0
  9. package/Styles/Elements/Progress/MarchingAntsProgressBar.cs +722 -0
  10. package/Styles/Elements/Progress/MarchingAntsProgressBar.cs.meta +3 -0
  11. package/Styles/Elements/{RegularProgressBar.cs → Progress/RegularProgressBar.cs} +24 -13
  12. package/Styles/Elements/Progress/WigglyProgressBar.cs +837 -0
  13. package/Styles/Elements/Progress/WigglyProgressBar.cs.meta +3 -0
  14. package/Styles/Elements/Progress.meta +3 -0
  15. package/Styles/USS/ArcedProgressBar.uss +19 -0
  16. package/Styles/USS/ArcedProgressBar.uss.meta +3 -0
  17. package/Styles/USS/WigglyProgressBar.uss +17 -0
  18. package/Styles/USS/WigglyProgressBar.uss.meta +3 -0
  19. package/package.json +2 -1
  20. package/Styles/UXML/CircularProgressBar.uxml +0 -11
  21. package/Styles/UXML/CircularProgressBar.uxml.meta +0 -10
  22. package/Styles/UXML/RegularProgressBar.uxml +0 -22
  23. package/Styles/UXML/RegularProgressBar.uxml.meta +0 -10
  24. package/Styles/UXML.meta +0 -3
  25. /package/Styles/Elements/{CircularProgressBar.cs.meta → Progress/CircularProgressBar.cs.meta} +0 -0
  26. /package/Styles/Elements/{RegularProgressBar.cs.meta → Progress/RegularProgressBar.cs.meta} +0 -0
@@ -0,0 +1,632 @@
1
+ namespace WallstopStudios.UnityHelpers.Styles.Elements.Progress
2
+ {
3
+ using UnityEngine;
4
+ using UnityEngine.UIElements;
5
+
6
+ public sealed class LiquidProgressBar : VisualElement
7
+ {
8
+ public const string USSClassName = "liquid-progress-bar";
9
+ public const string USSTrackColorVarName = "--lpb-track-color";
10
+ public const string USSTrackThicknessVarName = "--lpb-track-thickness";
11
+ public const string USSProgressColorVarName = "--lpb-progress-color";
12
+ public const string USSBorderRadiusVarName = "--lpb-border-radius";
13
+
14
+ private float _progress = 0.5f;
15
+ public float Progress
16
+ {
17
+ get => _progress;
18
+ set
19
+ {
20
+ if (float.IsNaN(value) || float.IsInfinity(value))
21
+ {
22
+ return;
23
+ }
24
+ _progress = Mathf.Clamp(value, 0.1095f, 1);
25
+ MarkDirtyRepaint();
26
+ }
27
+ }
28
+
29
+ private Color _trackColor = new(0.4f, 0.4f, 0.4f, 1f);
30
+ public Color TrackColor
31
+ {
32
+ get => _trackColor;
33
+ set
34
+ {
35
+ _trackColor = value;
36
+ MarkDirtyRepaint();
37
+ }
38
+ }
39
+
40
+ private float _trackThickness = 2f;
41
+ public float TrackThickness
42
+ {
43
+ get => _trackThickness;
44
+ set
45
+ {
46
+ if (float.IsNaN(value) || float.IsInfinity(value))
47
+ {
48
+ return;
49
+ }
50
+ _trackThickness = Mathf.Max(0.01f, value);
51
+ MarkDirtyRepaint();
52
+ }
53
+ }
54
+
55
+ private Color _progressColor = new(0.3f, 0.7f, 1f, 1f);
56
+ public Color ProgressColor
57
+ {
58
+ get => _progressColor;
59
+ set
60
+ {
61
+ _progressColor = value;
62
+ MarkDirtyRepaint();
63
+ }
64
+ }
65
+
66
+ private float _borderRadius = 7f;
67
+ public float BorderRadius
68
+ {
69
+ get => _borderRadius;
70
+ set
71
+ {
72
+ if (float.IsNaN(value) || float.IsInfinity(value))
73
+ {
74
+ return;
75
+ }
76
+ _borderRadius = Mathf.Max(0, value);
77
+ MarkDirtyRepaint();
78
+ }
79
+ }
80
+
81
+ private float _leadingEdgeCurvature = 0.6f;
82
+ public float LeadingEdgeCurvature
83
+ {
84
+ get => _leadingEdgeCurvature;
85
+ set
86
+ {
87
+ if (float.IsNaN(value) || float.IsInfinity(value))
88
+ {
89
+ return;
90
+ }
91
+ _leadingEdgeCurvature = Mathf.Clamp01(value);
92
+ MarkDirtyRepaint();
93
+ }
94
+ }
95
+
96
+ private float _animationSpeed = 2.5f;
97
+ public float AnimationSpeed
98
+ {
99
+ get => _animationSpeed;
100
+ set
101
+ {
102
+ if (float.IsNaN(value) || float.IsInfinity(value))
103
+ {
104
+ return;
105
+ }
106
+ _animationSpeed = Mathf.Max(0, value);
107
+ }
108
+ }
109
+
110
+ private float _wobbleMagnitude = 0.3f;
111
+ public float WobbleMagnitude
112
+ {
113
+ get => _wobbleMagnitude;
114
+ set
115
+ {
116
+ if (float.IsNaN(value) || float.IsInfinity(value))
117
+ {
118
+ return;
119
+ }
120
+ _wobbleMagnitude = Mathf.Clamp(value, 0f, 1f);
121
+ }
122
+ }
123
+
124
+ private bool _animateLeadingEdge = true;
125
+ public bool AnimateLeadingEdge
126
+ {
127
+ get => _animateLeadingEdge;
128
+ set
129
+ {
130
+ if (_animateLeadingEdge == value)
131
+ {
132
+ return;
133
+ }
134
+
135
+ _animateLeadingEdge = value;
136
+ if (_animateLeadingEdge)
137
+ {
138
+ if (panel != null)
139
+ {
140
+ StartAnimationUpdate();
141
+ }
142
+ }
143
+ else
144
+ {
145
+ StopAnimationUpdate();
146
+ _wobbleOffset = 0;
147
+ }
148
+ MarkDirtyRepaint();
149
+ }
150
+ }
151
+
152
+ private float _wobbleOffset;
153
+ private IVisualElementScheduledItem _animationUpdateItem;
154
+
155
+ public new class UxmlFactory : UxmlFactory<LiquidProgressBar, UxmlTraits> { }
156
+
157
+ public new class UxmlTraits : VisualElement.UxmlTraits
158
+ {
159
+ private readonly UxmlFloatAttributeDescription _progressAttribute = new()
160
+ {
161
+ name = "progress",
162
+ defaultValue = 0.5f,
163
+ };
164
+
165
+ private readonly UxmlColorAttributeDescription _trackColorAttribute = new()
166
+ {
167
+ name = "track-color",
168
+ defaultValue = new Color(0.4f, 0.4f, 0.4f, 1),
169
+ };
170
+
171
+ private readonly UxmlFloatAttributeDescription _trackThicknessAttribute = new()
172
+ {
173
+ name = "track-thickness",
174
+ defaultValue = 2f,
175
+ };
176
+
177
+ private readonly UxmlColorAttributeDescription _progressColorAttribute = new()
178
+ {
179
+ name = "progress-color",
180
+ defaultValue = new Color(0.3f, 0.7f, 1, 1),
181
+ };
182
+
183
+ private readonly UxmlFloatAttributeDescription _borderRadiusAttribute = new()
184
+ {
185
+ name = "border-radius",
186
+ defaultValue = 7f,
187
+ };
188
+
189
+ private readonly UxmlFloatAttributeDescription _leadingEdgeCurvatureAttribute = new()
190
+ {
191
+ name = "leading-edge-curvature",
192
+ defaultValue = 0.6f,
193
+ };
194
+
195
+ private readonly UxmlFloatAttributeDescription _animationSpeedAttribute = new()
196
+ {
197
+ name = "animation-speed",
198
+ defaultValue = 2.5f,
199
+ };
200
+
201
+ private readonly UxmlFloatAttributeDescription _wobbleMagnitudeAttribute = new()
202
+ {
203
+ name = "wobble-magnitude",
204
+ defaultValue = 0.3f,
205
+ };
206
+
207
+ private readonly UxmlBoolAttributeDescription _animateLeadingEdgeAttribute = new()
208
+ {
209
+ name = "animate-leading-edge",
210
+ defaultValue = true,
211
+ };
212
+
213
+ public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
214
+ {
215
+ base.Init(ve, bag, cc);
216
+
217
+ if (ve is not LiquidProgressBar bar)
218
+ {
219
+ Debug.LogError(
220
+ $"Initialization failed, expected {nameof(LiquidProgressBar)}, found {ve?.GetType()}.)"
221
+ );
222
+ return;
223
+ }
224
+
225
+ bar.Progress = _progressAttribute.GetValueFromBag(bag, cc);
226
+ bar.TrackColor = _trackColorAttribute.GetValueFromBag(bag, cc);
227
+ bar.TrackThickness = _trackThicknessAttribute.GetValueFromBag(bag, cc);
228
+ bar.ProgressColor = _progressColorAttribute.GetValueFromBag(bag, cc);
229
+ bar.BorderRadius = _borderRadiusAttribute.GetValueFromBag(bag, cc);
230
+ bar.LeadingEdgeCurvature = _leadingEdgeCurvatureAttribute.GetValueFromBag(bag, cc);
231
+ bar.AnimationSpeed = _animationSpeedAttribute.GetValueFromBag(bag, cc);
232
+ bar.WobbleMagnitude = _wobbleMagnitudeAttribute.GetValueFromBag(bag, cc);
233
+ bar.AnimateLeadingEdge = _animateLeadingEdgeAttribute.GetValueFromBag(bag, cc);
234
+
235
+ if (bar.style.height.keyword == StyleKeyword.Auto || bar.style.height.value == 0)
236
+ {
237
+ bar.style.height = 22;
238
+ }
239
+
240
+ if (bar.style.width.keyword == StyleKeyword.Auto || bar.style.width.value == 0)
241
+ {
242
+ bar.style.width = 200;
243
+ }
244
+ }
245
+ }
246
+
247
+ public LiquidProgressBar()
248
+ {
249
+ AddToClassList(USSClassName);
250
+ generateVisualContent += OnGenerateVisualContent;
251
+ RegisterCallback<CustomStyleResolvedEvent>(OnCustomStyleResolved);
252
+ RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
253
+ RegisterCallback<DetachFromPanelEvent>(OnDetachFromPanel);
254
+ }
255
+
256
+ private void OnAttachToPanel(AttachToPanelEvent evt)
257
+ {
258
+ if (_animateLeadingEdge)
259
+ {
260
+ StartAnimationUpdate();
261
+ }
262
+ }
263
+
264
+ private void OnDetachFromPanel(DetachFromPanelEvent evt)
265
+ {
266
+ StopAnimationUpdate();
267
+ }
268
+
269
+ private void StartAnimationUpdate()
270
+ {
271
+ if (!_animateLeadingEdge || panel == null || _animationUpdateItem != null)
272
+ {
273
+ return;
274
+ }
275
+
276
+ _animationUpdateItem = schedule.Execute(UpdateAnimation).Every(33);
277
+ }
278
+
279
+ private void StopAnimationUpdate()
280
+ {
281
+ _animationUpdateItem?.Pause();
282
+ _animationUpdateItem = null;
283
+ }
284
+
285
+ private void UpdateAnimation(TimerState ts)
286
+ {
287
+ if (!_animateLeadingEdge || panel == null)
288
+ {
289
+ StopAnimationUpdate();
290
+ _wobbleOffset = 0;
291
+ MarkDirtyRepaint();
292
+ return;
293
+ }
294
+ _wobbleOffset =
295
+ Mathf.Sin(Time.realtimeSinceStartup * _animationSpeed * 4f) * _wobbleMagnitude;
296
+ MarkDirtyRepaint();
297
+ }
298
+
299
+ private void OnCustomStyleResolved(CustomStyleResolvedEvent evt)
300
+ {
301
+ if (
302
+ customStyle.TryGetValue(
303
+ new CustomStyleProperty<Color>(USSTrackColorVarName),
304
+ out Color c
305
+ )
306
+ )
307
+ {
308
+ TrackColor = c;
309
+ }
310
+
311
+ if (
312
+ customStyle.TryGetValue(
313
+ new CustomStyleProperty<float>(USSTrackThicknessVarName),
314
+ out float tt
315
+ )
316
+ )
317
+ {
318
+ TrackThickness = tt;
319
+ }
320
+
321
+ if (
322
+ customStyle.TryGetValue(
323
+ new CustomStyleProperty<Color>(USSProgressColorVarName),
324
+ out Color pc
325
+ )
326
+ )
327
+ {
328
+ ProgressColor = pc;
329
+ }
330
+
331
+ if (
332
+ customStyle.TryGetValue(
333
+ new CustomStyleProperty<float>(USSBorderRadiusVarName),
334
+ out float br
335
+ )
336
+ )
337
+ {
338
+ BorderRadius = br;
339
+ }
340
+ }
341
+
342
+ private void OnGenerateVisualContent(MeshGenerationContext mgc)
343
+ {
344
+ Painter2D painter = mgc.painter2D;
345
+ Rect r = contentRect;
346
+
347
+ if (r.width <= 0 || r.height <= 0)
348
+ {
349
+ return;
350
+ }
351
+
352
+ float barHeight = r.height;
353
+ float halfHeight = barHeight / 2f;
354
+
355
+ float outerRadius = Mathf.Min(_borderRadius, halfHeight, r.width / 2f);
356
+ if (Mathf.Approximately(outerRadius, 0))
357
+ {
358
+ outerRadius = 0;
359
+ }
360
+
361
+ float trackThickness = _trackThickness;
362
+ if (Mathf.Approximately(trackThickness, 0))
363
+ {
364
+ trackThickness = 0;
365
+ }
366
+
367
+ float halfTrackThickness = trackThickness / 2f;
368
+ Rect fillRect = new(
369
+ r.xMin + halfTrackThickness,
370
+ r.yMin + halfTrackThickness,
371
+ r.width - trackThickness,
372
+ r.height - trackThickness
373
+ );
374
+
375
+ bool fillRectIsValid = fillRect is { width: > 0, height: > 0 };
376
+ float innerRadius = Mathf.Max(0, outerRadius - halfTrackThickness);
377
+
378
+ if (!Mathf.Approximately(trackThickness, 0))
379
+ {
380
+ painter.strokeColor = _trackColor;
381
+ painter.fillColor = Color.clear;
382
+ painter.lineWidth = trackThickness;
383
+ painter.lineCap = LineCap.Butt;
384
+ painter.lineJoin = LineJoin.Miter;
385
+
386
+ painter.BeginPath();
387
+ painter.MoveTo(new Vector2(r.xMin + outerRadius, r.yMin));
388
+ painter.LineTo(new Vector2(r.xMax - outerRadius, r.yMin));
389
+ if (outerRadius > 0)
390
+ {
391
+ painter.Arc(
392
+ new Vector2(r.xMax - outerRadius, r.yMin + outerRadius),
393
+ outerRadius,
394
+ 270f,
395
+ 90f
396
+ );
397
+ }
398
+
399
+ painter.LineTo(new Vector2(r.xMax, r.yMax - outerRadius));
400
+ if (outerRadius > 0)
401
+ {
402
+ painter.Arc(
403
+ new Vector2(r.xMax - outerRadius, r.yMax - outerRadius),
404
+ outerRadius,
405
+ 0f,
406
+ 90f
407
+ );
408
+ }
409
+
410
+ painter.LineTo(new Vector2(r.xMin + outerRadius, r.yMax));
411
+ if (outerRadius > 0)
412
+ {
413
+ painter.Arc(
414
+ new Vector2(r.xMin + outerRadius, r.yMax - outerRadius),
415
+ outerRadius,
416
+ 90f,
417
+ 90f
418
+ );
419
+ }
420
+
421
+ painter.LineTo(new Vector2(r.xMin, r.yMin + outerRadius));
422
+ if (outerRadius > 0)
423
+ {
424
+ painter.Arc(
425
+ new Vector2(r.xMin + outerRadius, r.yMin + outerRadius),
426
+ outerRadius,
427
+ 180f,
428
+ 90f
429
+ );
430
+ }
431
+ painter.Stroke();
432
+ }
433
+
434
+ if (
435
+ !fillRectIsValid
436
+ || (
437
+ Mathf.Approximately(_progress, 0)
438
+ && Mathf.Approximately(_wobbleOffset, 0)
439
+ && Mathf.Approximately(_wobbleMagnitude, 0)
440
+ )
441
+ )
442
+ {
443
+ return;
444
+ }
445
+
446
+ painter.fillColor = _progressColor;
447
+ float baseFillWidth = fillRect.width * _progress;
448
+ float wobbleExtension = _wobbleOffset * fillRect.height * 0.3f;
449
+ float currentTotalFillWidth = baseFillWidth + wobbleExtension;
450
+ currentTotalFillWidth = Mathf.Clamp(currentTotalFillWidth, 0, fillRect.width);
451
+
452
+ if (currentTotalFillWidth < 0.5f)
453
+ {
454
+ return;
455
+ }
456
+
457
+ painter.BeginPath();
458
+
459
+ float capRadius = fillRect.height / 2f;
460
+ if (Mathf.Approximately(capRadius, 0))
461
+ {
462
+ capRadius = 0;
463
+ }
464
+
465
+ bool drawPillShape = currentTotalFillWidth < fillRect.height && _progress < 0.99f;
466
+
467
+ if (drawPillShape)
468
+ {
469
+ float pillActualRadius = Mathf.Min(currentTotalFillWidth / 2.0f, capRadius);
470
+ if (Mathf.Approximately(pillActualRadius, 0))
471
+ {
472
+ pillActualRadius = 0;
473
+ }
474
+
475
+ float straightSegmentWidth = Mathf.Max(
476
+ 0,
477
+ currentTotalFillWidth - 2 * pillActualRadius
478
+ );
479
+
480
+ painter.MoveTo(new Vector2(fillRect.xMin + pillActualRadius, fillRect.yMin));
481
+ if (straightSegmentWidth > 0)
482
+ {
483
+ painter.LineTo(
484
+ new Vector2(
485
+ fillRect.xMin + pillActualRadius + straightSegmentWidth,
486
+ fillRect.yMin
487
+ )
488
+ );
489
+ }
490
+
491
+ if (pillActualRadius > 0)
492
+ {
493
+ painter.Arc(
494
+ new Vector2(
495
+ fillRect.xMin + pillActualRadius + straightSegmentWidth,
496
+ fillRect.yMin + pillActualRadius
497
+ ),
498
+ pillActualRadius,
499
+ 270f,
500
+ 180f
501
+ );
502
+ }
503
+ else
504
+ {
505
+ painter.LineTo(
506
+ new Vector2(fillRect.xMin + currentTotalFillWidth, fillRect.yMax)
507
+ );
508
+ }
509
+
510
+ if (straightSegmentWidth > 0)
511
+ {
512
+ painter.LineTo(new Vector2(fillRect.xMin + pillActualRadius, fillRect.yMax));
513
+ }
514
+
515
+ if (pillActualRadius > 0)
516
+ {
517
+ painter.Arc(
518
+ new Vector2(
519
+ fillRect.xMin + pillActualRadius,
520
+ fillRect.yMin + pillActualRadius
521
+ ),
522
+ pillActualRadius,
523
+ 90f,
524
+ 180f
525
+ );
526
+ }
527
+ }
528
+ else
529
+ {
530
+ float animatedPeakX = fillRect.xMin + currentTotalFillWidth;
531
+ painter.MoveTo(new Vector2(fillRect.xMin + innerRadius, fillRect.yMin));
532
+
533
+ bool useLiquidEdge =
534
+ _progress < 0.995f
535
+ && _leadingEdgeCurvature > 0.01f
536
+ && animatedPeakX < fillRect.xMax - innerRadius - 0.1f
537
+ && currentTotalFillWidth > innerRadius * 2.1f;
538
+
539
+ if (useLiquidEdge)
540
+ {
541
+ float curveStartBaseX =
542
+ animatedPeakX - fillRect.height * _leadingEdgeCurvature * 0.4f;
543
+ curveStartBaseX = Mathf.Max(fillRect.xMin + innerRadius, curveStartBaseX);
544
+ painter.LineTo(new Vector2(curveStartBaseX, fillRect.yMin));
545
+
546
+ Vector2 peak = new(animatedPeakX, fillRect.yMin + fillRect.height / 2f);
547
+ float controlPointBulgeXFactor = fillRect.height * _leadingEdgeCurvature * 0.5f;
548
+ Vector2 cp1Top = new(
549
+ curveStartBaseX + (peak.x - curveStartBaseX) * 0.35f,
550
+ fillRect.yMin
551
+ );
552
+ Vector2 cp2Top = new(
553
+ peak.x + controlPointBulgeXFactor,
554
+ peak.y - fillRect.height * 0.25f
555
+ );
556
+ painter.BezierCurveTo(cp1Top, cp2Top, peak);
557
+
558
+ Vector2 cp1Bottom = new(
559
+ peak.x + controlPointBulgeXFactor,
560
+ peak.y + fillRect.height * 0.25f
561
+ );
562
+ Vector2 cp2Bottom = new(
563
+ curveStartBaseX + (peak.x - curveStartBaseX) * 0.35f,
564
+ fillRect.yMax
565
+ );
566
+ painter.BezierCurveTo(
567
+ cp1Bottom,
568
+ cp2Bottom,
569
+ new Vector2(curveStartBaseX, fillRect.yMax)
570
+ );
571
+ }
572
+ else
573
+ {
574
+ painter.LineTo(new Vector2(animatedPeakX - innerRadius, fillRect.yMin));
575
+ if (innerRadius > 0)
576
+ {
577
+ painter.Arc(
578
+ new Vector2(animatedPeakX - innerRadius, fillRect.yMin + innerRadius),
579
+ innerRadius,
580
+ 270f,
581
+ 90f
582
+ );
583
+ }
584
+ else
585
+ {
586
+ painter.LineTo(new Vector2(animatedPeakX, fillRect.yMin));
587
+ }
588
+
589
+ painter.LineTo(new Vector2(animatedPeakX, fillRect.yMax - innerRadius));
590
+ if (innerRadius > 0)
591
+ {
592
+ painter.Arc(
593
+ new Vector2(animatedPeakX - innerRadius, fillRect.yMax - innerRadius),
594
+ innerRadius,
595
+ 0f,
596
+ 90f
597
+ );
598
+ }
599
+ else
600
+ {
601
+ painter.LineTo(new Vector2(animatedPeakX, fillRect.yMax));
602
+ }
603
+ }
604
+
605
+ painter.LineTo(new Vector2(fillRect.xMin + innerRadius, fillRect.yMax));
606
+ if (innerRadius > 0)
607
+ {
608
+ painter.Arc(
609
+ new Vector2(fillRect.xMin + innerRadius, fillRect.yMax - innerRadius),
610
+ innerRadius,
611
+ 90f,
612
+ 90f
613
+ );
614
+ }
615
+
616
+ painter.LineTo(new Vector2(fillRect.xMin, fillRect.yMin + innerRadius));
617
+ if (innerRadius > 0)
618
+ {
619
+ painter.Arc(
620
+ new Vector2(fillRect.xMin + innerRadius, fillRect.yMin + innerRadius),
621
+ innerRadius,
622
+ 180f,
623
+ 90f
624
+ );
625
+ }
626
+ }
627
+
628
+ painter.ClosePath();
629
+ painter.Fill();
630
+ }
631
+ }
632
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: ea08a1426a7942ba924e31942f11046c
3
+ timeCreated: 1746740255