CompareTrack.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. using System;
  2. using System.Windows;
  3. using System.Windows.Controls;
  4. using System.Windows.Controls.Primitives;
  5. namespace HandyControl.Controls;
  6. public class CompareTrack : Track
  7. {
  8. protected override Size ArrangeOverride(Size arrangeSize)
  9. {
  10. base.ArrangeOverride(arrangeSize);
  11. var isVertical = Orientation == Orientation.Vertical;
  12. ComputeSliderLengths(arrangeSize, isVertical, out var decreaseButtonLength, out var thumbLength,
  13. out var increaseButtonLength);
  14. var offset = new Point();
  15. var pieceSize = arrangeSize;
  16. var isDirectionReversed = IsDirectionReversed;
  17. if (isVertical)
  18. {
  19. CoerceLength(ref decreaseButtonLength, arrangeSize.Height);
  20. CoerceLength(ref increaseButtonLength, arrangeSize.Height);
  21. CoerceLength(ref thumbLength, arrangeSize.Height);
  22. offset.Y = isDirectionReversed ? decreaseButtonLength + thumbLength : 0.0;
  23. pieceSize.Height = increaseButtonLength;
  24. IncreaseRepeatButton?.Arrange(new Rect(offset, pieceSize));
  25. offset.Y = isDirectionReversed ? 0.0 : increaseButtonLength + thumbLength;
  26. pieceSize.Height = decreaseButtonLength;
  27. if (DecreaseRepeatButton != null)
  28. {
  29. DecreaseRepeatButton.Arrange(new Rect(offset, pieceSize));
  30. DecreaseRepeatButton.Height = pieceSize.Height;
  31. }
  32. offset.Y = isDirectionReversed ? decreaseButtonLength : increaseButtonLength;
  33. pieceSize.Height = thumbLength;
  34. Thumb?.Arrange(new Rect(offset, pieceSize));
  35. }
  36. else
  37. {
  38. CoerceLength(ref decreaseButtonLength, arrangeSize.Width);
  39. CoerceLength(ref increaseButtonLength, arrangeSize.Width);
  40. CoerceLength(ref thumbLength, arrangeSize.Width);
  41. offset.X = isDirectionReversed ? increaseButtonLength + thumbLength : 0.0;
  42. pieceSize.Width = decreaseButtonLength;
  43. DecreaseRepeatButton?.Arrange(new Rect(offset, pieceSize));
  44. offset.X = isDirectionReversed ? 0.0 : decreaseButtonLength + thumbLength;
  45. pieceSize.Width = increaseButtonLength;
  46. if (IncreaseRepeatButton != null)
  47. {
  48. IncreaseRepeatButton.Arrange(new Rect(offset, pieceSize));
  49. IncreaseRepeatButton.Width = pieceSize.Width;
  50. }
  51. offset.X = isDirectionReversed ? increaseButtonLength : decreaseButtonLength;
  52. pieceSize.Width = thumbLength;
  53. Thumb?.Arrange(new Rect(offset, pieceSize));
  54. }
  55. return arrangeSize;
  56. }
  57. private void ComputeSliderLengths(Size arrangeSize, bool isVertical, out double decreaseButtonLength,
  58. out double thumbLength, out double increaseButtonLength)
  59. {
  60. var min = Minimum;
  61. var range = Math.Max(0.0, Maximum - min);
  62. var offset = Math.Min(range, Value - min);
  63. double trackLength;
  64. // Compute thumb size
  65. if (isVertical)
  66. {
  67. trackLength = arrangeSize.Height;
  68. thumbLength = Thumb?.DesiredSize.Height ?? 0;
  69. }
  70. else
  71. {
  72. trackLength = arrangeSize.Width;
  73. thumbLength = Thumb?.DesiredSize.Width ?? 0;
  74. }
  75. CoerceLength(ref thumbLength, trackLength);
  76. var remainingTrackLength = trackLength - thumbLength;
  77. decreaseButtonLength = remainingTrackLength * offset / range;
  78. CoerceLength(ref decreaseButtonLength, remainingTrackLength);
  79. increaseButtonLength = remainingTrackLength - decreaseButtonLength;
  80. CoerceLength(ref increaseButtonLength, remainingTrackLength);
  81. }
  82. private static void CoerceLength(ref double componentLength, double trackLength)
  83. {
  84. if (componentLength < 0)
  85. componentLength = 0.0;
  86. else if (componentLength > trackLength || double.IsNaN(componentLength))
  87. componentLength = trackLength;
  88. }
  89. }