MenuScrollingVisibilityConverter.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using Avalonia.Controls.Primitives;
  5. using Avalonia.Data.Converters;
  6. using Avalonia.Utilities;
  7. namespace Avalonia.Controls.Converters
  8. {
  9. public class MenuScrollingVisibilityConverter : IMultiValueConverter
  10. {
  11. public static readonly MenuScrollingVisibilityConverter Instance = new MenuScrollingVisibilityConverter();
  12. public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
  13. {
  14. if (parameter == null ||
  15. values == null ||
  16. values.Count != 4 ||
  17. !(values[0] is ScrollBarVisibility visibility) ||
  18. !(values[1] is double offset) ||
  19. !(values[2] is double extent) ||
  20. !(values[3] is double viewport))
  21. {
  22. return AvaloniaProperty.UnsetValue;
  23. }
  24. if (visibility == ScrollBarVisibility.Auto)
  25. {
  26. if (MathUtilities.AreClose(extent, viewport))
  27. {
  28. return false;
  29. }
  30. double target;
  31. if (parameter is double d)
  32. {
  33. target = d;
  34. }
  35. else if (parameter is string s)
  36. {
  37. target = double.Parse(s, NumberFormatInfo.InvariantInfo);
  38. }
  39. else
  40. {
  41. return AvaloniaProperty.UnsetValue;
  42. }
  43. // Calculate the percent so that we can see if we are near the edge of the range
  44. double percent = MathUtilities.Clamp(offset * 100.0 / (extent - viewport), 0, 100);
  45. if (MathUtilities.AreClose(percent, target))
  46. {
  47. // We are at the end of the range, so no need for this button to be shown
  48. return false;
  49. }
  50. return true;
  51. }
  52. return false;
  53. }
  54. }
  55. }