using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Dominion.NET_WPF.Caching;
namespace Dominion.NET_WPF.Controls
{
///
/// SmallBrushPicker user control
/// This code is open source published with the Code Project Open License (CPOL).
///
public partial class ucSmallBrushPicker : UserControl
{
public static readonly DependencyProperty SelectedIndexProperty;
public static readonly DependencyProperty SelectedItemProperty;
public static readonly DependencyProperty TextBrushProperty;
//private static Dictionary average_hash = new Dictionary();
static ucSmallBrushPicker()
{
SelectedIndexProperty = DependencyProperty.Register
("SelectedIndex", typeof(int), typeof(ucSmallBrushPicker));
SelectedItemProperty = DependencyProperty.Register
("SelectedItem", typeof(Brush), typeof(ucSmallBrushPicker));
TextBrushProperty = DependencyProperty.Register
("TextBrush", typeof(Brush), typeof(ucSmallBrushPicker));
}
public int SelectedIndex
{
get { return (int)GetValue(SelectedIndexProperty); }
set { SetValue(SelectedIndexProperty, value); }
}
public object SelectedItem
{
get
{
return GetValue(SelectedItemProperty) as Brush;
}
set { SetValue(SelectedItemProperty, value); }
}
public object TextBrush
{
get
{
return GetValue(TextBrushProperty) as Brush;
}
set { SetValue(TextBrushProperty, value); }
}
public ObservableCollection ImageBrushes { get; set; }
public ucSmallBrushPicker()
{
ImageBrushes = new ObservableCollection();
TextBrush = Brushes.Black;
Clear();
InitializeComponent();
var selectedIndexBinding = new Binding("SelectedIndex")
{
Source = Content,
Mode = BindingMode.TwoWay
};
SetBinding(SelectedIndexProperty, selectedIndexBinding);
var selectedItemBinding = new Binding("SelectedItem")
{
Source = Content,
Mode = BindingMode.TwoWay
};
SetBinding(SelectedItemProperty, selectedItemBinding);
}
#region Dependency properties
public Brush SelectedBrush
{
get { return (Brush)GetValue(SelectedBrushProperty); }
set { SetValue(SelectedBrushProperty, value); }
}
public static readonly DependencyProperty SelectedBrushProperty =
DependencyProperty.Register("SelectedBrush", typeof(Brush), typeof(ucSmallBrushPicker),
new FrameworkPropertyMetadata(OnSelectedBrushChanged));
public IEnumerable AvailableBrushes => ImageBrushes.OfType();
private bool ListContains(Brush newBrush)
{
return Picker.Items.OfType().Contains(newBrush);
}
private static void OnSelectedBrushChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
var bp = obj as ucSmallBrushPicker;
Debug.Assert(bp != null);
var newBrush = (Brush)args.NewValue;
var oldBrush = (Brush)args.OldValue;
if (Equals(newBrush, oldBrush))
return;
// When the SelectedBrush changes, set the selected value of the combo box
if (bp.Picker.SelectedValue == null || !Equals((Brush)bp.Picker.SelectedValue, newBrush))
{
// Add the brush if not found
if (!bp.ListContains(newBrush))
{
bp.AddBrush(newBrush);
}
}
bp.OnBrushChanged(oldBrush, newBrush);
}
#endregion
#region Events
public static readonly RoutedEvent BrushChangedEvent =
EventManager.RegisterRoutedEvent("BrushChanged", RoutingStrategy.Bubble,
typeof(RoutedPropertyChangedEventHandler), typeof(ucSmallBrushPicker));
public event RoutedPropertyChangedEventHandler BrushChanged
{
add { AddHandler(BrushChangedEvent, value); }
remove { RemoveHandler(BrushChangedEvent, value); }
}
protected virtual void OnBrushChanged(Brush oldValue, Brush newValue)
{
var args = new RoutedPropertyChangedEventArgs(oldValue, newValue) {RoutedEvent = BrushChangedEvent};
RaiseEvent(args);
}
#endregion
public static Brush CheckerBrush { get; } = CreateCheckerBrush();
public void Clear()
{
ImageBrushes.Clear();
ImageBrushes.Add(Brushes.Transparent);
//this.SelectedItem = Brushes.Transparent;
}
///
/// Add a brush to the BrushPicker list
///
///
public void AddBrush(Brush b)
{
ImageBrushes.Add(b);
}
public static Brush CreateCheckerBrush()
{
// from http://msdn.microsoft.com/en-us/library/aa970904.aspx
var checkerBrush = new DrawingBrush();
int width;
var height = width = 16;
const int size = 4;
var backgroundSquare =
new GeometryDrawing(
Brushes.White,
null,
new RectangleGeometry(new Rect(0, 0, width, height)));
var aGeometryGroup = new GeometryGroup();
for (var x = 0; x < width; x += size)
{
for (var y = 0; y < height; y += size)
{
if ((x + y) / size % 2 == 1)
continue;
aGeometryGroup.Children.Add(new RectangleGeometry(new Rect(x, y, size, size)));
}
}
var checkers = new GeometryDrawing(Brushes.Black, null, aGeometryGroup);
var checkersDrawingGroup = new DrawingGroup();
checkersDrawingGroup.Children.Add(backgroundSquare);
checkersDrawingGroup.Children.Add(checkers);
checkerBrush.Drawing = checkersDrawingGroup;
checkerBrush.Viewport = new Rect(0, 0, 0.5, 0.5);
checkerBrush.TileMode = TileMode.Tile;
return checkerBrush;
}
private void Picker_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var addedBrushes = e.AddedItems.OfType().ToList();
if (addedBrushes.Any())
{
var addedImage = addedBrushes.First().ImageSource;
var image = addedImage as BitmapImage;
if (image != null)
{
var ir = ImageRepository.Acquire();
TextBrush = ir.GetForegroundBrush(image);
ImageRepository.Release();
//BitmapImage image = (BitmapImage)addedImage;
//if (!average_hash.ContainsKey(image))
//{
// PixelColor[,] pixels = ImageUtilities.GetPixels(image);
// double l_sum = 0;
// for (int x = 0; x < pixels.GetLength(0); x++)
// {
// for (int y = 0; y < pixels.GetLength(1); y++)
// {
// Color c = Color.FromArgb(pixels[x, y].Alpha, pixels[x, y].Red, pixels[x, y].Green, pixels[x, y].Blue);
// double l = 0.2126 * c.ScR + 0.7152 * c.ScG + 0.0722 * c.ScB;
// l_sum += l;
// }
// }
// average_hash[image] = l_sum / (pixels.GetLength(0) * pixels.GetLength(1));
//}
//if (average_hash[image] < 0.5)
// this.TextBrush = Brushes.White;
//else
// this.TextBrush = Brushes.Black;
}
else
TextBrush = Brushes.Black;
}
else
TextBrush = Brushes.Black;
OnBrushChanged(e.RemovedItems.OfType().FirstOrDefault(), e.AddedItems.OfType().FirstOrDefault());
}
}
public class BindingProxy : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object Data
{
get { return GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
// Using a DependencyProperty as the backing store for Data.
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
}