// (c) Copyright ESRI.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using ESRI.ArcGIS.Client.Symbols;
using System.ComponentModel;
using System;
using System.Windows.Markup;
namespace ESRI.ArcGIS.Client.Toolkit.Primitives
{
///
/// A control that displays a symbol presenter scaled to fit.
///
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public class SymbolDisplay : Control
{
DataBinder data = new DataBinder();
private ContentPresenter ChildElement { get; set; }
private ScaleTransform Scale { get; set; }
SymbolPresenter presenter = new SymbolPresenter();
///
/// The symbol presenter
///
public SymbolPresenter SymbolContent { get { return presenter; } }
///
/// Constructor.
///
public SymbolDisplay()
{
string temp = "";
#if SILVERLIGHT
Template = System.Windows.Markup.XamlReader.Load(temp) as ControlTemplate;
#else
System.IO.MemoryStream templateStream = new System.IO.MemoryStream(System.Text.UTF8Encoding.Default.GetBytes(temp));
Template = System.Windows.Markup.XamlReader.Load(templateStream) as ControlTemplate;
#endif
ApplyTemplate();
base.IsTabStop = false;
}
///
/// Overrides OnApplyTemplate
///
public override void OnApplyTemplate()
{
this.ChildElement = base.GetTemplateChild("Child") as ContentPresenter;
this.ChildElement.RenderTransform = this.Scale = new ScaleTransform();
this.ChildElement.Content = presenter;
this.SymbolContent.DataContext = data;
}
///
/// The symbol to display
///
public Symbol Symbol
{
get { return (Symbol)GetValue(SymbolProperty); }
set { SetValue(SymbolProperty, value); }
}
///
/// Overrides MeasureOverride
///
///
///
protected override Size MeasureOverride(Size availableSize)
{
Size size = new Size();
if (this.ChildElement != null)
{
this.ChildElement.Measure((Symbol is MarkerSymbol)
? new Size(double.PositiveInfinity, double.PositiveInfinity) : availableSize);
Size desiredSize = this.ChildElement.DesiredSize;
double factor = ComputeScaleFactor(availableSize, desiredSize);
size.Width = desiredSize.Width * factor;
size.Height = desiredSize.Height * factor;
}
return size;
}
private static double ComputeScaleFactor(Size availableSize, Size desiredSize)
{
return Math.Min(1, Math.Min(availableSize.Width / desiredSize.Width,
availableSize.Height / desiredSize.Height));
}
///
/// Overrides ArrangeOverride
///
///
///
protected override Size ArrangeOverride(Size finalSize)
{
if (this.ChildElement != null)
{
Size desiredSize = this.ChildElement.DesiredSize;
double factor = ComputeScaleFactor(finalSize, desiredSize);
this.Scale.ScaleX = factor;
this.Scale.ScaleY = factor;
Rect finalRect = new Rect(0.0, 0.0, desiredSize.Width, desiredSize.Height);
this.ChildElement.Arrange(finalRect);
finalSize.Width = factor * desiredSize.Width;
finalSize.Height = factor * desiredSize.Height;
}
return finalSize;
}
///
/// Identifies the dependency property.
///
public static readonly DependencyProperty SymbolProperty =
DependencyProperty.Register("Symbol", typeof(Symbol), typeof(SymbolDisplay), new PropertyMetadata(OnSymbolPropertyChanged));
private static void OnSymbolPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SymbolDisplay obj = (SymbolDisplay)d;
obj.SymbolContent.Symbol = obj.data.Symbol = e.NewValue as Symbol;
}
///
/// The attributes. Required for data binding
///
public Dictionary Attributes
{
get { return (Dictionary)GetValue(AttributesProperty); }
set { SetValue(AttributesProperty, value); }
}
///
/// Identifies the dependency property.
///
public static readonly DependencyProperty AttributesProperty =
DependencyProperty.Register("Attributes", typeof(IDictionary), typeof(SymbolDisplay), new PropertyMetadata(null, OnAttributesPropertyChanged));
private static void OnAttributesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SymbolDisplay obj = (SymbolDisplay)d;
obj.data.Attributes = (IDictionary)e.NewValue;
}
///
/// The data binder. Used for data binding.
///
public class DataBinder : INotifyPropertyChanged
{
IDictionary attributes;
///
/// Attributes
///
public IDictionary Attributes
{
get { return attributes; }
set
{
attributes = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Attributes"));
}
}
Symbol symbol;
///
/// Symbol
///
public Symbol Symbol {
get { return symbol; }
set
{
symbol = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Symbol"));
}
}
#region INotifyPropertyChanged Members
///
/// Property changed event.
///
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
}
}