| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- using Avalonia;
- using Avalonia.Controls;
- using Avalonia.Media;
- using YZWater.Core.Utils;
- namespace YZWater.Avalonia.Controls;
- /// <summary>
- /// 鑷傚簲瀹瑰櫒鎺т欢 - 鏍规嵁绐楀彛澶у皬鑷姩缂╂斁鍐呭
- /// </summary>
- public class AdaptiveContainer : Decorator
- {
- public static readonly StyledProperty<double> DesignWidthProperty =
- AvaloniaProperty.Register<AdaptiveContainer, double>(nameof(DesignWidth), ResolutionManager.DesignWidth);
- public static readonly StyledProperty<double> DesignHeightProperty =
- AvaloniaProperty.Register<AdaptiveContainer, double>(nameof(DesignHeight), ResolutionManager.DesignHeight);
- public static readonly StyledProperty<bool> MaintainAspectRatioProperty =
- AvaloniaProperty.Register<AdaptiveContainer, bool>(nameof(MaintainAspectRatio), true);
- public static readonly StyledProperty<Stretch> StretchProperty =
- AvaloniaProperty.Register<AdaptiveContainer, Stretch>(nameof(Stretch), Stretch.Uniform);
- public static readonly StyledProperty<double> MinScaleProperty =
- AvaloniaProperty.Register<AdaptiveContainer, double>(nameof(MinScale), 0.5);
- public static readonly StyledProperty<double> MaxScaleProperty =
- AvaloniaProperty.Register<AdaptiveContainer, double>(nameof(MaxScale), 2.0);
- public double DesignWidth
- {
- get => GetValue(DesignWidthProperty);
- set => SetValue(DesignWidthProperty, value);
- }
- public double DesignHeight
- {
- get => GetValue(DesignHeightProperty);
- set => SetValue(DesignHeightProperty, value);
- }
- public bool MaintainAspectRatio
- {
- get => GetValue(MaintainAspectRatioProperty);
- set => SetValue(MaintainAspectRatioProperty, value);
- }
- public Stretch Stretch
- {
- get => GetValue(StretchProperty);
- set => SetValue(StretchProperty, value);
- }
- public double MinScale
- {
- get => GetValue(MinScaleProperty);
- set => SetValue(MinScaleProperty, value);
- }
- public double MaxScale
- {
- get => GetValue(MaxScaleProperty);
- set => SetValue(MaxScaleProperty, value);
- }
- static AdaptiveContainer()
- {
- AffectsMeasure<AdaptiveContainer>(DesignWidthProperty, DesignHeightProperty, MaintainAspectRatioProperty, StretchProperty, MinScaleProperty, MaxScaleProperty);
- AffectsArrange<AdaptiveContainer>(DesignWidthProperty, DesignHeightProperty, MaintainAspectRatioProperty, StretchProperty, MinScaleProperty, MaxScaleProperty);
- }
- protected override Size MeasureOverride(Size availableSize)
- {
- var child = Child;
- if (child == null)
- {
- return new Size(0, 0);
- }
- // 璁╁瓙鍏冪礌鎸夌収璁捐灏哄娴嬮噺
- var designSize = new Size(DesignWidth, DesignHeight);
- child.Measure(designSize);
- // 璁$畻鍙敤绌洪棿
- var availableWidth = availableSize.Width;
- var availableHeight = availableSize.Height;
- // 濡傛灉鍙敤绌洪棿鏄棤闄愮殑锛屼娇鐢ㄨ璁″昂瀵
- if (double.IsInfinity(availableWidth))
- {
- availableWidth = DesignWidth;
- }
- if (double.IsInfinity(availableHeight))
- {
- availableHeight = DesignHeight;
- }
- // 杩斿洖鍙敤绌洪棿锛堝疄闄呯缉鏀惧湪 Arrange 闃舵澶勭悊锛
- return new Size(availableWidth, availableHeight);
- }
- protected override Size ArrangeOverride(Size finalSize)
- {
- var child = Child;
- if (child == null)
- {
- return finalSize;
- }
- // 璁$畻缂╂斁姣斾緥
- var scaleX = finalSize.Width / DesignWidth;
- var scaleY = finalSize.Height / DesignHeight;
- var scale = Stretch switch
- {
- Stretch.Fill => new ScaleTransform(scaleX, scaleY),
- Stretch.Uniform => new ScaleTransform(Math.Min(scaleX, scaleY), Math.Min(scaleX, scaleY)),
- Stretch.UniformToFill => new ScaleTransform(Math.Max(scaleX, scaleY), Math.Max(scaleX, scaleY)),
- _ => new ScaleTransform(1, 1)
- };
- // 闄愬埗缂╂斁鑼冨洿
- var uniformScale = Math.Max(MinScale, Math.Min(MaxScale, scale.ScaleX));
- // 鏇存柊鍒嗚鲸鐜囩鐞嗗櫒
- ResolutionManager.Instance.UpdateResolution(finalSize.Width, finalSize.Height);
- // 璁$畻瀹為檯灏哄
- var actualWidth = DesignWidth * uniformScale;
- var actualHeight = DesignHeight * uniformScale;
- // 璁$畻灞呬腑鍋忕Щ
- var offsetX = (finalSize.Width - actualWidth) / 2;
- var offsetY = (finalSize.Height - actualHeight) / 2;
- // 搴旂敤鍙樻崲
- child.RenderTransform = new ScaleTransform(uniformScale, uniformScale);
- child.RenderTransformOrigin = new RelativePoint(0, 0, RelativeUnit.Absolute);
- // 鎺掑垪瀛愬厓绱
- child.Arrange(new Rect(offsetX, offsetY, DesignWidth, DesignHeight));
- return finalSize;
- }
- }
|