using System; using System.Collections.Generic; using System.Globalization; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Media; namespace Controls { /// /// Magically converts a text to /// [ValueConversion(typeof(string), typeof(FrameworkElement))] public class MagicSymbolConverter : IValueConverter { private const string NoParseKeyword = "noParse:"; private const string PathKeyword = "path:"; private const string DynResKeyword = "dynRes:"; /// public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return ConvertToFrameworkElement(value); } /// /// Convert string to Framework element. /// /// /// public static object ConvertToFrameworkElement(object value) { var data = value as string; if (string.IsNullOrWhiteSpace(data)) return value; //maybe not a string. eventually something else. if (data.StartsWith(NoParseKeyword, StringComparison.Ordinal)) return data[NoParseKeyword.Length..]; if (data.StartsWith(PathKeyword, StringComparison.Ordinal)) { var path = data[PathKeyword.Length..]; var icon = ObjectImageConverter.GetIcon(Geometry.Parse(path), Brushes.Black); return new Image { Source = icon, HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Center, Height = 16 }; } if (data.StartsWith(DynResKeyword, StringComparison.Ordinal)) { var resourceKey = data[DynResKeyword.Length..]; //get icon from resource dictionary return new Image { Source = Application.Current.FindResource(resourceKey) as ImageSource, HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Center, Height = 16 }; } var textComponents = ParseText(data); return CreateTextBlock(textComponents); } private static TextBlock CreateTextBlock(IEnumerable textComponents) { //create text block var block = new TextBlock(); foreach (var tc in textComponents) { var run = new Run(tc.Text) {FontFamily = new FontFamily("Palatino Linotype"), FontSize = 16}; switch (tc.Style) { case BaselineAlignment.Subscript: run.BaselineAlignment = BaselineAlignment.Subscript; run.FontSize = 12; break; case BaselineAlignment.Superscript: run.BaselineAlignment = BaselineAlignment.Superscript; run.FontSize = 12; break; } block.Inlines.Add(run); } block.HorizontalAlignment = HorizontalAlignment.Right; block.VerticalAlignment = VerticalAlignment.Center; return block; } private static IEnumerable ParseText(string data) { //parse text var textComponents = new List(); var alignment = BaselineAlignment.Baseline; var snippet = new StringBuilder(); foreach (var c in data) { switch (c) { case '~': if (snippet.Length > 0) { var comp = new TextComponent(snippet.ToString(), alignment); textComponents.Add(comp); snippet.Clear(); } alignment = alignment == BaselineAlignment.Subscript ? BaselineAlignment.Baseline : BaselineAlignment.Subscript; break; case '^': if (snippet.Length > 0) { var comp = new TextComponent(snippet.ToString(), alignment); textComponents.Add(comp); snippet.Clear(); } alignment = alignment == BaselineAlignment.Superscript ? BaselineAlignment.Baseline : BaselineAlignment.Superscript; break; default: snippet.Append(c); break; } } if (snippet.Length > 0) { var comp = new TextComponent(snippet.ToString(), alignment); textComponents.Add(comp); snippet.Clear(); } return textComponents; } /// public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => Binding.DoNothing; } }