53 lines
2.0 KiB
C#
53 lines
2.0 KiB
C#
using System.Globalization;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Data;
|
|
|
|
namespace RQOverlay;
|
|
|
|
/// <summary>bool -> Visibility. ConverterParameter="!" инвертирует.</summary>
|
|
public sealed class BoolToVis : IValueConverter
|
|
{
|
|
public object Convert(object value, Type t, object? p, CultureInfo c)
|
|
{
|
|
bool v = value is true;
|
|
if (p as string == "!") v = !v;
|
|
return v ? Visibility.Visible : Visibility.Collapsed;
|
|
}
|
|
|
|
public object ConvertBack(object value, Type t, object? p, CultureInfo c) => throw new NotSupportedException();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Панель-полоска: делит ширину между детьми пропорционально их весу
|
|
/// (присоединённое свойство Weight). Для полоски долей дохода.
|
|
/// </summary>
|
|
public sealed class ShareStrip : Panel
|
|
{
|
|
public static readonly DependencyProperty WeightProperty = DependencyProperty.RegisterAttached(
|
|
"Weight", typeof(double), typeof(ShareStrip),
|
|
new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsParentArrange));
|
|
|
|
public static double GetWeight(DependencyObject o) => (double)o.GetValue(WeightProperty);
|
|
public static void SetWeight(DependencyObject o, double v) => o.SetValue(WeightProperty, v);
|
|
|
|
protected override Size MeasureOverride(Size available)
|
|
{
|
|
foreach (UIElement child in InternalChildren) child.Measure(available);
|
|
return new Size(0, 0); // растягиваемся на всё, что дадут
|
|
}
|
|
|
|
protected override Size ArrangeOverride(Size final)
|
|
{
|
|
double total = InternalChildren.Cast<UIElement>().Sum(c => Math.Max(0, GetWeight(c)));
|
|
double x = 0;
|
|
foreach (UIElement child in InternalChildren)
|
|
{
|
|
double w = total > 0 ? final.Width * Math.Max(0, GetWeight(child)) / total : 0;
|
|
child.Arrange(new Rect(x, 0, w, final.Height));
|
|
x += w;
|
|
}
|
|
return final;
|
|
}
|
|
}
|