Added MapControl.UiTools.MapLayerInfo

This commit is contained in:
ClemensFischer 2025-09-16 14:18:29 +02:00
parent c31780a298
commit d23bc99f3d
16 changed files with 332 additions and 161 deletions

View file

@ -0,0 +1,44 @@
<UserControl
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:md="clr-namespace:Markdown.Avalonia;assembly=Markdown.Avalonia"
xmlns:local="clr-namespace:MapControl.UiTools"
x:Class="MapControl.UiTools.MapLayerInfo"
x:Name="mapLayerInfo">
<UserControl.Styles>
<Style Selector="local|MapLayerInfo">
<Setter Property="Padding" Value="4,0"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
</Style>
</UserControl.Styles>
<StackPanel
Orientation="Horizontal"
Background="{Binding Background, ElementName=mapLayerInfo}"
DataContext="{Binding ElementName=mapLayerInfo}">
<ProgressBar
VerticalAlignment="Center" Margin="{Binding Padding}"
Maximum="1" Value="{Binding MapLayer.LoadingProgress}">
<ProgressBar.IsVisible>
<Binding Path="Value" RelativeSource="{RelativeSource Self}">
<Binding.Converter>
<local:ProgressVisibilityConverter/>
</Binding.Converter>
</Binding>
</ProgressBar.IsVisible>
</ProgressBar>
<LayoutTransformControl Margin="{Binding Padding}">
<LayoutTransformControl.LayoutTransform>
<ScaleTransform ScaleX="0.8" ScaleY="0.8"/>
</LayoutTransformControl.LayoutTransform>
<md:MarkdownScrollViewer Markdown="{Binding MapLayer.Description}"/>
</LayoutTransformControl>
</StackPanel>
</UserControl>

View file

@ -10,11 +10,22 @@
<Compile Include="..\Shared\*.cs" />
</ItemGroup>
<ItemGroup>
<Compile Remove="..\Shared\HyperlinkText.cs" />
</ItemGroup>
<ItemGroup>
<AvaloniaXaml Include="MapLayerInfo.xaml">
<Generator>MSBuild:Compile</Generator>
</AvaloniaXaml>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\MapControl\Avalonia\MapControl.Avalonia.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.3.6" />
<PackageReference Include="Markdown.Avalonia.Tight" Version="11.0.2" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
#if WINUI
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Documents;
#elif UWP
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Documents;
#else
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
#endif
namespace MapControl.UiTools
{
public static class HyperlinkText
{
private static readonly Regex regex = new Regex(@"\[([^\]]+)\]\(([^\)]+)\)");
/// <summary>
/// Converts text containing hyperlinks in markdown syntax [text](url)
/// to a collection of Run and Hyperlink inlines.
/// </summary>
public static IEnumerable<Inline> TextToInlines(this string text)
{
var inlines = new List<Inline>();
while (!string.IsNullOrEmpty(text))
{
var match = regex.Match(text);
if (match.Success &&
match.Groups.Count == 3 &&
Uri.TryCreate(match.Groups[2].Value, UriKind.Absolute, out Uri uri))
{
inlines.Add(new Run { Text = text.Substring(0, match.Index) });
text = text.Substring(match.Index + match.Length);
var link = new Hyperlink { NavigateUri = uri };
link.Inlines.Add(new Run { Text = match.Groups[1].Value });
#if WPF
link.ToolTip = uri.ToString();
link.RequestNavigate += (s, e) =>
{
try
{
Process.Start(new ProcessStartInfo(e.Uri.ToString()) { UseShellExecute = true });
}
catch (Exception ex)
{
Debug.WriteLine($"{e.Uri}: {ex}");
}
};
#endif
inlines.Add(link);
}
else
{
inlines.Add(new Run { Text = text });
text = null;
}
}
return inlines;
}
public static readonly DependencyProperty InlinesSourceProperty = DependencyProperty.RegisterAttached(
"InlinesSource", typeof(string), typeof(HyperlinkText), new PropertyMetadata(null, InlinesSourcePropertyChanged));
public static string GetInlinesSource(DependencyObject element)
{
return (string)element.GetValue(InlinesSourceProperty);
}
public static void SetInlinesSource(DependencyObject element, string value)
{
element.SetValue(InlinesSourceProperty, value);
}
private static void InlinesSourcePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
InlineCollection inlines = null;
if (obj is TextBlock block)
{
inlines = block.Inlines;
}
else if (obj is Paragraph paragraph)
{
inlines = paragraph.Inlines;
}
if (inlines != null)
{
inlines.Clear();
foreach (var inline in TextToInlines((string)e.NewValue))
{
inlines.Add(inline);
}
}
}
}
}

View file

@ -0,0 +1,34 @@
#if WPF
using System.Windows;
using System.Windows.Controls;
#elif UWP
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
#elif WINUI
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
#else
using Avalonia.Controls;
using DependencyProperty = Avalonia.AvaloniaProperty;
using FrameworkElement = Avalonia.Controls.Control;
#endif
namespace MapControl.UiTools
{
public partial class MapLayerInfo : UserControl
{
public static readonly DependencyProperty MapLayerProperty =
DependencyPropertyHelper.Register<MapLayerInfo, FrameworkElement>(nameof(MapLayer), null);
public FrameworkElement MapLayer
{
get => (FrameworkElement)GetValue(MapLayerProperty);
set => SetValue(MapLayerProperty, value);
}
public MapLayerInfo()
{
InitializeComponent();
}
}
}

View file

@ -0,0 +1,45 @@
using System;
using System.Globalization;
#if WPF
using System.Windows;
using System.Windows.Data;
#elif UWP
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
#elif WINUI
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Data;
#else
using Avalonia.Data.Converters;
#endif
namespace MapControl.UiTools
{
internal partial class ProgressVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var visible = (double)value < 1d;
#if AVALONIA
return visible;
#else
return visible ? Visibility.Visible : Visibility.Collapsed;
#endif
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Convert(value, targetType, parameter, culture.ToString());
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View file

@ -0,0 +1,44 @@
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MapControl.UiTools"
x:Class="MapControl.UiTools.MapLayerInfo"
x:Name="mapLayerInfo">
<UserControl.Resources>
<Style TargetType="local:MapLayerInfo">
<Setter Property="Padding" Value="6,3"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
</Style>
<Style TargetType="ProgressBar">
<Setter Property="Width" Value="100"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="10"/>
</Style>
</UserControl.Resources>
<StackPanel
Orientation="Horizontal"
Background="{Binding Background, ElementName=mapLayerInfo}"
DataContext="{Binding ElementName=mapLayerInfo}">
<ProgressBar
VerticalAlignment="Center" Margin="{Binding Padding}"
Maximum="1" Value="{Binding MapLayer.LoadingProgress}">
<ProgressBar.Visibility>
<Binding Path="Value" RelativeSource="{RelativeSource Self}">
<Binding.Converter>
<local:ProgressVisibilityConverter/>
</Binding.Converter>
</Binding>
</ProgressBar.Visibility>
</ProgressBar>
<TextBlock
VerticalAlignment="Center" Margin="{Binding Padding}"
local:HyperlinkText.InlinesSource="{Binding MapLayer.Description}"/>
</StackPanel>
</UserControl>

View file

@ -0,0 +1,42 @@
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MapControl.UiTools"
x:Class="MapControl.UiTools.MapLayerInfo">
<UserControl.Resources>
<Style TargetType="local:MapLayerInfo">
<Setter Property="Padding" Value="4,2"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
</Style>
<Style TargetType="ProgressBar">
<Setter Property="Width" Value="100"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="10"/>
</Style>
</UserControl.Resources>
<StackPanel
Orientation="Horizontal"
DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}">
<ProgressBar
VerticalAlignment="Center" Margin="{Binding Padding}"
Maximum="1" Value="{Binding MapLayer.LoadingProgress}">
<ProgressBar.Visibility>
<Binding Path="Value" RelativeSource="{RelativeSource Self}">
<Binding.Converter>
<local:ProgressVisibilityConverter/>
</Binding.Converter>
</Binding>
</ProgressBar.Visibility>
</ProgressBar>
<TextBlock
Margin="{Binding Padding}"
local:HyperlinkText.InlinesSource="{Binding MapLayer.Description}"/>
</StackPanel>
</UserControl>

View file

@ -0,0 +1,44 @@
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MapControl.UiTools"
x:Class="MapControl.UiTools.MapLayerInfo"
x:Name="mapLayerInfo">
<UserControl.Resources>
<Style TargetType="local:MapLayerInfo">
<Setter Property="Padding" Value="6,3"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
</Style>
<Style TargetType="ProgressBar">
<Setter Property="Width" Value="100"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="10"/>
</Style>
</UserControl.Resources>
<StackPanel
Orientation="Horizontal"
Background="{Binding Background, ElementName=mapLayerInfo}"
DataContext="{Binding ElementName=mapLayerInfo}">
<ProgressBar
VerticalAlignment="Center" Margin="{Binding Padding}"
Maximum="1" Value="{Binding MapLayer.LoadingProgress}">
<ProgressBar.Visibility>
<Binding Path="Value" RelativeSource="{RelativeSource Self}">
<Binding.Converter>
<local:ProgressVisibilityConverter/>
</Binding.Converter>
</Binding>
</ProgressBar.Visibility>
</ProgressBar>
<TextBlock
VerticalAlignment="Center" Margin="{Binding Padding}"
local:HyperlinkText.InlinesSource="{Binding MapLayer.Description}"/>
</StackPanel>
</UserControl>