using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary;
using System.Windows.Threading;
using System.Diagnostics;
namespace Microsoft.Research.DynamicDataDisplay
{
public partial class Viewport2D
{
#region IsContentBoundsHost attached property
public static bool GetIsContentBoundsHost(DependencyObject obj)
{
return (bool)obj.GetValue(IsContentBoundsHostProperty);
}
public static void SetIsContentBoundsHost(DependencyObject obj, bool value)
{
obj.SetValue(IsContentBoundsHostProperty, value);
}
public static readonly DependencyProperty IsContentBoundsHostProperty = DependencyProperty.RegisterAttached(
"IsContentBoundsHost",
typeof(bool),
typeof(Viewport2D),
new FrameworkPropertyMetadata(true, OnIsContentBoundsChanged));
private static void OnIsContentBoundsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
IPlotterElement plotterElement = d as IPlotterElement;
if (plotterElement != null && plotterElement.Plotter != null)
{
Plotter2D plotter2d = (Plotter2D)plotterElement.Plotter;
plotter2d.Viewport.UpdateContentBoundsHosts();
}
}
#endregion
#region ContentBounds attached property
public static DataRect GetContentBounds(DependencyObject obj)
{
return (DataRect)obj.GetValue(ContentBoundsProperty);
}
public static void SetContentBounds(DependencyObject obj, DataRect value)
{
obj.SetValue(ContentBoundsProperty, value);
}
public static readonly DependencyProperty ContentBoundsProperty = DependencyProperty.RegisterAttached(
"ContentBounds",
typeof(DataRect),
typeof(Viewport2D),
new FrameworkPropertyMetadata(DataRect.Empty, OnContentBoundsChanged, CoerceContentBounds));
private static object CoerceContentBounds(DependencyObject d, object value)
{
DataRect prevBounds = GetContentBounds(d);
DataRect currBounds = (DataRect)value;
bool approximateComparanceAllowed = GetUsesApproximateContentBoundsComparison(d);
bool areClose = approximateComparanceAllowed && currBounds.IsCloseTo(prevBounds, 0.005);
if (areClose)
return DependencyProperty.UnsetValue;
else
return value;
}
private static void OnContentBoundsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
IPlotterElement element = d as IPlotterElement;
if (element != null)
{
FrameworkElement frElement = element as FrameworkElement;
if (frElement != null)
{
frElement.RaiseEvent(new RoutedEventArgs(ContentBoundsChangedEvent));
}
Plotter2D plotter2d = element.Plotter as Plotter2D;
if (plotter2d != null)
{
plotter2d.Viewport.UpdateContentBoundsHosts();
}
}
}
public static readonly RoutedEvent ContentBoundsChangedEvent = EventManager.RegisterRoutedEvent(
"ContentBoundsChanged",
RoutingStrategy.Direct,
typeof(RoutedEventHandler),
typeof(Viewport2D));
#endregion
#region UsesApproximateContentBoundsComparison
///
/// Gets a value indicating whether approximate content bounds comparison will be used while deciding whether to updating Viewport2D.ContentBounds
/// attached dependency property or not.
/// Approximate content bounds comparison can make Viewport's Visible to changed less frequent, but it can lead to
/// some bugs if content bounds are large but visible area is not compared to them.
///
///
/// true if approximate content bounds comparison is used while deciding whether to set new value of content bounds, or not; otherwise, false.
///
public static bool GetUsesApproximateContentBoundsComparison(DependencyObject obj)
{
return (bool)obj.GetValue(UsesApproximateContentBoundsComparisonProperty);
}
///
/// Sets a value indicating whether approximate content bounds comparison will be used while deciding whether to updating Viewport2D.ContentBounds
/// attached dependency property or not.
/// Approximate content bounds comparison can make Viewport's Visible to changed less frequent, but it can lead to
/// some bugs if content bounds are large but visible area is not compared to them.
///
///
/// true if approximate content bounds comparison is used while deciding whether to set new value of content bounds, or not; otherwise, false.
///
public static void SetUsesApproximateContentBoundsComparison(DependencyObject obj, bool value)
{
obj.SetValue(UsesApproximateContentBoundsComparisonProperty, value);
}
public static readonly DependencyProperty UsesApproximateContentBoundsComparisonProperty = DependencyProperty.RegisterAttached(
"UsesApproximateContentBoundsComparison",
typeof(bool),
typeof(Viewport2D),
new FrameworkPropertyMetadata(true, OnUsesApproximateContentBoundsComparisonChanged));
private static void OnUsesApproximateContentBoundsComparisonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
IPlotterElement element = d as IPlotterElement;
if (element != null)
{
Plotter2D plotter2d = element.Plotter as Plotter2D;
if (plotter2d != null)
{
plotter2d.Viewport.UpdateVisible();
}
}
}
#endregion // end of UsesApproximateContentBoundsComparison
#region UseDeferredPanning attached property
public static bool GetUseDeferredPanning(DependencyObject obj)
{
return (bool)obj.GetValue(UseDeferredPanningProperty);
}
public static void SetUseDeferredPanning(DependencyObject obj, bool value)
{
obj.SetValue(UseDeferredPanningProperty, value);
}
public static readonly DependencyProperty UseDeferredPanningProperty = DependencyProperty.RegisterAttached(
"UseDeferredPanning",
typeof(bool),
typeof(Viewport2D),
new FrameworkPropertyMetadata(false));
#endregion // end of UseDeferredPanning attached property
}
}