using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary; using Microsoft.Research.DynamicDataDisplay.Common; using System.ComponentModel; namespace Microsoft.Research.DynamicDataDisplay.Charts.Axes { /// /// Contains data for custom generation of tick's label. /// /// Type of ticks public sealed class LabelTickInfo { internal LabelTickInfo() { } /// /// Gets or sets the tick. /// /// The tick. public T Tick { get; internal set; } /// /// Gets or sets additional info about ticks range. /// /// The info. public object Info { get; internal set; } /// /// Gets or sets the index of tick in ticks array. /// /// The index. public int Index { get; internal set; } } /// /// Base class for all label providers. /// Contains a number of properties that can be used to adjust generated labels. /// /// Type of ticks, which labels are generated for /// /// Order of apllication of custom label string properties: /// If CustomFormatter is not null, it is called first. /// Then, if it was null or if it returned null string, /// virtual GetStringCore method is called. It can be overloaded in subclasses. GetStringCore should not return null. /// Then if LabelStringFormat is not null, it is applied. /// After label's UI was created, you can change it by setting CustomView delegate - it allows you to adjust /// UI properties of label. Note: not all labelProviders takes CustomView into account. /// public abstract class LabelProviderBase { #region Private private string labelStringFormat = null; private Func, string> customFormatter = null; private Action, UIElement> customView = null; #endregion private static readonly UIElement[] emptyLabelsArray = new UIElement[0]; protected static UIElement[] EmptyLabelsArray { get { return emptyLabelsArray; } } /// /// Creates labels by given ticks info. /// Is not intended to be called from your code. /// /// The ticks info. /// Array of s, which are axis labels for specified axis ticks. [EditorBrowsable(EditorBrowsableState.Never)] public abstract UIElement[] CreateLabels(ITicksInfo ticksInfo); /// /// Gets or sets the label string format. /// /// The label string format. public string LabelStringFormat { get { return labelStringFormat; } set { if (labelStringFormat != value) { labelStringFormat = value; RaiseChanged(); } } } /// /// Gets or sets the custom formatter - delegate that can be called to create custom string representation of tick. /// /// The custom formatter. public Func, string> CustomFormatter { get { return customFormatter; } set { if (customFormatter != value) { customFormatter = value; RaiseChanged(); } } } /// /// Gets or sets the custom view - delegate that is used to create a custom, non-default look of axis label. /// Can be used to adjust some UI properties of generated label. /// /// The custom view. public Action, UIElement> CustomView { get { return customView; } set { if (customView != value) { customView = value; RaiseChanged(); } } } /// /// Sets the custom formatter. /// This is alternative to CustomFormatter property setter, the only difference is that Visual Studio shows /// more convenient tooltip for methods rather than for properties' setters. /// /// The formatter. public void SetCustomFormatter(Func, string> formatter) { CustomFormatter = formatter; } /// /// Sets the custom view. /// This is alternative to CustomView property setter, the only difference is that Visual Studio shows /// more convenient tooltip for methods rather than for properties' setters. /// /// The view. public void SetCustomView(Action, UIElement> view) { CustomView = view; } protected virtual string GetString(LabelTickInfo tickInfo) { string text = null; if (CustomFormatter != null) { text = CustomFormatter(tickInfo); } if (text == null) { text = GetStringCore(tickInfo); if (text == null) throw new ArgumentNullException(Strings.Exceptions.TextOfTickShouldNotBeNull); } if (LabelStringFormat != null) { text = String.Format(LabelStringFormat, text); } return text; } protected virtual string GetStringCore(LabelTickInfo tickInfo) { return tickInfo.Tick.ToString(); } protected void ApplyCustomView(LabelTickInfo info, UIElement label) { if (CustomView != null) { CustomView(info, label); } } /// /// Occurs when label provider is changed. /// Notifies axis to update its view. /// public event EventHandler Changed; protected void RaiseChanged() { Changed.Raise(this); } private readonly ResourcePool pool = new ResourcePool(); internal void ReleaseLabel(UIElement label) { if (ReleaseCore(label)) { pool.Put(label); } } protected virtual bool ReleaseCore(UIElement label) { return false; } protected UIElement GetResourceFromPool() { return pool.Get(); } } }