175 lines
5.9 KiB
C#
175 lines
5.9 KiB
C#
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
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <value>
|
|
/// <c>true</c> if approximate content bounds comparison is used while deciding whether to set new value of content bounds, or not; otherwise, <c>false</c>.
|
|
/// </value>
|
|
public static bool GetUsesApproximateContentBoundsComparison(DependencyObject obj)
|
|
{
|
|
return (bool)obj.GetValue(UsesApproximateContentBoundsComparisonProperty);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <value>
|
|
/// <c>true</c> if approximate content bounds comparison is used while deciding whether to set new value of content bounds, or not; otherwise, <c>false</c>.
|
|
/// </value>
|
|
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
|
|
}
|
|
}
|