GeometrySource`1.cs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using System.Windows;
  2. using System.Windows.Media;
  3. using HandyControl.Expression.Drawing;
  4. namespace HandyControl.Expression.Media;
  5. public abstract class GeometrySource<TParameters> : IGeometrySource
  6. where TParameters : IGeometrySourceParameters
  7. {
  8. private bool _geometryInvalidated;
  9. protected Geometry CachedGeometry;
  10. public bool InvalidateGeometry(InvalidateGeometryReasons reasons)
  11. {
  12. if ((reasons & InvalidateGeometryReasons.TemplateChanged) != 0) CachedGeometry = null;
  13. if (!_geometryInvalidated)
  14. {
  15. _geometryInvalidated = true;
  16. return true;
  17. }
  18. return false;
  19. }
  20. public bool UpdateGeometry(IGeometrySourceParameters parameters, Rect layoutBounds)
  21. {
  22. var force = false;
  23. if (parameters is TParameters parameters1)
  24. {
  25. var rect = ComputeLogicalBounds(layoutBounds, parameters1);
  26. force |= LayoutBounds != layoutBounds || LogicalBounds != rect;
  27. if (_geometryInvalidated || force)
  28. {
  29. LayoutBounds = layoutBounds;
  30. LogicalBounds = rect;
  31. force |= UpdateCachedGeometry(parameters1);
  32. force |= ApplyGeometryEffect(parameters1, force);
  33. }
  34. }
  35. _geometryInvalidated = false;
  36. return force;
  37. }
  38. public Geometry Geometry { get; private set; }
  39. public Rect LayoutBounds { get; private set; }
  40. public Rect LogicalBounds { get; private set; }
  41. private bool ApplyGeometryEffect(IGeometrySourceParameters parameters, bool force)
  42. {
  43. var flag = false;
  44. var cachedGeometry = CachedGeometry;
  45. var geometryEffect = parameters.GetGeometryEffect();
  46. if (geometryEffect != null)
  47. {
  48. if (force)
  49. {
  50. flag = true;
  51. geometryEffect.InvalidateGeometry(InvalidateGeometryReasons.ParentInvalidated);
  52. }
  53. if (geometryEffect.ProcessGeometry(CachedGeometry))
  54. {
  55. flag = true;
  56. cachedGeometry = geometryEffect.OutputGeometry;
  57. }
  58. }
  59. if (!Equals(Geometry, cachedGeometry))
  60. {
  61. flag = true;
  62. Geometry = cachedGeometry;
  63. }
  64. return flag;
  65. }
  66. protected virtual Rect ComputeLogicalBounds(Rect layoutBounds, IGeometrySourceParameters parameters)
  67. {
  68. return GeometryHelper.Inflate(layoutBounds, -parameters.GetHalfStrokeThickness());
  69. }
  70. protected abstract bool UpdateCachedGeometry(TParameters parameters);
  71. }