using System; using System.Globalization; using System.Windows; using System.Windows.Media; namespace SourceGit.Views.Controls { /// /// 变更状态图标 /// class ChangeStatusIcon : FrameworkElement { public static readonly DependencyProperty ChangeProperty = DependencyProperty.Register( "Change", typeof(Models.Change), typeof(ChangeStatusIcon), new PropertyMetadata(null, ForceDirty)); public Models.Change Change { get { return (Models.Change)GetValue(ChangeProperty); } set { SetValue(ChangeProperty, value); } } public static readonly DependencyProperty IsLocalChangeProperty = DependencyProperty.Register( "IsLocalChange", typeof(bool), typeof(ChangeStatusIcon), new PropertyMetadata(false, ForceDirty)); public bool IsLocalChange { get { return (bool)GetValue(IsLocalChangeProperty); } set { SetValue(IsLocalChangeProperty, value); } } private Brush background; private FormattedText label; public ChangeStatusIcon() { HorizontalAlignment = HorizontalAlignment.Center; VerticalAlignment = VerticalAlignment.Center; } protected override void OnRender(DrawingContext dc) { if (background == null || label == null) return; var corner = Math.Max(2, Width / 16); dc.DrawRoundedRectangle(background, null, new Rect(0, 0, Width, Height), corner, corner); dc.DrawText(label, new Point((Width - label.Width) * 0.5, 0)); } private static void ForceDirty(DependencyObject d, DependencyPropertyChangedEventArgs e) { var icon = d as ChangeStatusIcon; if (icon == null) return; if (icon.Change == null) { icon.background = null; icon.label = null; return; } string txt; if (icon.IsLocalChange) { if (icon.Change.IsConflit) { icon.background = Brushes.OrangeRed; txt = "!"; } else { icon.background = GetBackground(icon.Change.WorkTree); txt = GetLabel(icon.Change.WorkTree); } } else { icon.background = GetBackground(icon.Change.Index); txt = GetLabel(icon.Change.Index); } icon.label = new FormattedText( txt, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(new FontFamily("Consolas"), FontStyles.Normal, FontWeights.Normal, FontStretches.Normal), icon.Width * 0.8, new SolidColorBrush(Color.FromRgb(241,241,241)), VisualTreeHelper.GetDpi(icon).PixelsPerDip); icon.InvalidateVisual(); } private static Brush GetBackground(Models.Change.Status status) { switch (status) { case Models.Change.Status.Modified: return new LinearGradientBrush(Color.FromRgb(238, 160, 14), Color.FromRgb(228, 172, 67), 90); case Models.Change.Status.Added: return new LinearGradientBrush(Color.FromRgb(47, 185, 47), Color.FromRgb(75, 189, 75), 90); case Models.Change.Status.Deleted: return new LinearGradientBrush(Colors.Tomato, Color.FromRgb(252, 165, 150), 90); case Models.Change.Status.Renamed: return new LinearGradientBrush(Colors.Orchid, Color.FromRgb(248, 161, 245), 90); case Models.Change.Status.Copied: return new LinearGradientBrush(Color.FromRgb(238, 160, 14), Color.FromRgb(228, 172, 67), 90); case Models.Change.Status.Unmerged: return new LinearGradientBrush(Color.FromRgb(238, 160, 14), Color.FromRgb(228, 172, 67), 90); case Models.Change.Status.Untracked: return new LinearGradientBrush(Color.FromRgb(47, 185, 47), Color.FromRgb(75, 189, 75), 90); default: return Brushes.Transparent; } } private static string GetLabel(Models.Change.Status status) { switch (status) { case Models.Change.Status.Modified: return "±"; case Models.Change.Status.Added: return "✚"; case Models.Change.Status.Deleted: return "▬"; case Models.Change.Status.Renamed: return "➔"; case Models.Change.Status.Copied: return "❏"; case Models.Change.Status.Unmerged: return "∪"; case Models.Change.Status.Untracked: return "★"; default: return "?"; } } } }