Browse Source
<extToolkit:MagnifierManager.Magnifier>
<extToolkit:Magnifier Radius="150" ZoomFactor="0.5" />
</extToolkit:MagnifierManager.Magnifier>
pull/1645/head
7 changed files with 446 additions and 1 deletions
@ -0,0 +1,24 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Data; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Mag.Converters |
||||
|
{ |
||||
|
internal class BorderThicknessToStrokeThicknessConverter : IValueConverter |
||||
|
{ |
||||
|
#region IValueConverter Members
|
||||
|
|
||||
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
Thickness thickness = (Thickness)value; |
||||
|
return (thickness.Bottom + thickness.Left + thickness.Right + thickness.Top) / 4; |
||||
|
} |
||||
|
|
||||
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Data; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Mag.Converters |
||||
|
{ |
||||
|
internal class RadiusConverter : IValueConverter |
||||
|
{ |
||||
|
#region IValueConverter Members
|
||||
|
|
||||
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
return (double)value * 2; |
||||
|
} |
||||
|
|
||||
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,166 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class Magnifier : Control |
||||
|
{ |
||||
|
#region Properties
|
||||
|
|
||||
|
#region DefaultSize
|
||||
|
|
||||
|
internal Size DefaultSize |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return new Size(2 * Radius, 2 * Radius); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //DefaultSize
|
||||
|
|
||||
|
#region MagnifierWidth
|
||||
|
|
||||
|
public static readonly DependencyProperty MagnifierWidthProperty = DependencyProperty.Register("MagnifierWidth", typeof(double), typeof(Magnifier), new UIPropertyMetadata(50.0)); |
||||
|
internal double MagnifierWidth |
||||
|
{ |
||||
|
get { return (double)GetValue(MagnifierWidthProperty); } |
||||
|
set { SetValue(MagnifierWidthProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //MagnifierWidth
|
||||
|
|
||||
|
#region MagnifierHeight
|
||||
|
|
||||
|
public static readonly DependencyProperty MagnifierHeightProperty = DependencyProperty.Register("MagnifierHeight", typeof(double), typeof(Magnifier), new UIPropertyMetadata(50.0)); |
||||
|
internal double MagnifierHeight |
||||
|
{ |
||||
|
get { return (double)GetValue(MagnifierHeightProperty); } |
||||
|
set { SetValue(MagnifierHeightProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //MagnifierWidth
|
||||
|
|
||||
|
#region Radius
|
||||
|
|
||||
|
public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register("Radius", typeof(double), typeof(Magnifier), new FrameworkPropertyMetadata(50.0, new PropertyChangedCallback(OnRadiusPropertyChanged))); |
||||
|
public double Radius |
||||
|
{ |
||||
|
get { return (double)GetValue(RadiusProperty); } |
||||
|
set { SetValue(RadiusProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnRadiusPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
Magnifier m = (Magnifier)d; |
||||
|
m.OnRadiusChanged(e); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnRadiusChanged(DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ResolveViewBox(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Radius
|
||||
|
|
||||
|
#region Target
|
||||
|
|
||||
|
public static readonly DependencyProperty TargetProperty = DependencyProperty.Register("Target", typeof(UIElement), typeof(Magnifier)); |
||||
|
public UIElement Target |
||||
|
{ |
||||
|
get { return (UIElement)GetValue(TargetProperty); } |
||||
|
set { SetValue(TargetProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Target
|
||||
|
|
||||
|
#region ViewBox
|
||||
|
|
||||
|
public static readonly DependencyProperty ViewBoxProperty = DependencyProperty.Register("ViewBox", typeof(Rect), typeof(Magnifier), new FrameworkPropertyMetadata(default(Rect))); |
||||
|
internal Rect ViewBox |
||||
|
{ |
||||
|
get { return (Rect)GetValue(ViewBoxProperty); } |
||||
|
set { SetValue(ViewBoxProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //ViewBox
|
||||
|
|
||||
|
#region ZoomFactor
|
||||
|
|
||||
|
public static readonly DependencyProperty ZoomFactorProperty = DependencyProperty.Register("ZoomFactor", typeof(double), typeof(Magnifier), new FrameworkPropertyMetadata(0.5, OnZoomFactorPropertyChanged, OnCoerceZoomFactorProperty)); |
||||
|
public double ZoomFactor |
||||
|
{ |
||||
|
get { return (double)GetValue(ZoomFactorProperty); } |
||||
|
set { SetValue(ZoomFactorProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnZoomFactorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
Magnifier m = (Magnifier)d; |
||||
|
m.OnZoomFactorChanged(e); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnZoomFactorChanged(DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ResolveViewBox(); |
||||
|
} |
||||
|
|
||||
|
private static object OnCoerceZoomFactorProperty(DependencyObject d, object value) |
||||
|
{ |
||||
|
Magnifier m = (Magnifier)d; |
||||
|
return m.OnCoerceZoomFactor(value); |
||||
|
} |
||||
|
|
||||
|
protected virtual object OnCoerceZoomFactor(object value) |
||||
|
{ |
||||
|
double zoomFactor = (double)value; |
||||
|
|
||||
|
if (zoomFactor > 1) |
||||
|
zoomFactor = 1; |
||||
|
else if (zoomFactor < 0) |
||||
|
zoomFactor = 0; |
||||
|
|
||||
|
return zoomFactor; |
||||
|
} |
||||
|
|
||||
|
#endregion //ZoomFactor
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes static members of the <see cref="Magnifier"/> class.
|
||||
|
/// </summary>
|
||||
|
static Magnifier() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(Magnifier), new FrameworkPropertyMetadata(typeof(Magnifier))); |
||||
|
} |
||||
|
|
||||
|
public Magnifier() |
||||
|
{ |
||||
|
ResolveViewBox(); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
private void ResolveViewBox() |
||||
|
{ |
||||
|
double correction = (BorderThickness.Bottom + BorderThickness.Left + BorderThickness.Right + BorderThickness.Top == 0) ? 1 : 0; |
||||
|
|
||||
|
double width = DefaultSize.Width * ZoomFactor; |
||||
|
double height = DefaultSize.Height * ZoomFactor; |
||||
|
|
||||
|
MagnifierWidth = DefaultSize.Width - correction; |
||||
|
MagnifierHeight = DefaultSize.Height - correction; |
||||
|
|
||||
|
ViewBox = new Rect(ViewBox.Location, new Size(width, height)); |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,96 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Documents; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Input; |
||||
|
using System.Windows.Media; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class MagnifierAdorner : Adorner |
||||
|
{ |
||||
|
#region Members
|
||||
|
|
||||
|
private Magnifier _magnifier; |
||||
|
private Point _currentMousePosition; |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
public MagnifierAdorner(UIElement element, Magnifier magnifier) |
||||
|
: base(element) |
||||
|
{ |
||||
|
InputManager.Current.PostProcessInput += Current_PostProcessInput; |
||||
|
_magnifier = magnifier; |
||||
|
UpdateViewBox(); |
||||
|
AddVisualChild(_magnifier); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region Private/Internal methods
|
||||
|
|
||||
|
private void Current_PostProcessInput(object sender, ProcessInputEventArgs e) |
||||
|
{ |
||||
|
Point pt = Mouse.GetPosition(this); |
||||
|
|
||||
|
if (_currentMousePosition == pt) |
||||
|
return; |
||||
|
|
||||
|
_currentMousePosition = pt; |
||||
|
UpdateViewBox(); |
||||
|
InvalidateArrange(); |
||||
|
} |
||||
|
|
||||
|
internal void UpdateViewBox() |
||||
|
{ |
||||
|
var viewBoxLocation = CalculateViewBoxLocation(); |
||||
|
_magnifier.ViewBox = new Rect(viewBoxLocation, _magnifier.ViewBox.Size); |
||||
|
} |
||||
|
|
||||
|
private Point CalculateViewBoxLocation() |
||||
|
{ |
||||
|
double offsetX = 0, offsetY = 0; |
||||
|
|
||||
|
Point adorner = Mouse.GetPosition(this); |
||||
|
Point element = Mouse.GetPosition(AdornedElement); |
||||
|
|
||||
|
offsetX = element.X - adorner.X; |
||||
|
offsetY = element.Y - adorner.Y; |
||||
|
|
||||
|
double left = _currentMousePosition.X - ((_magnifier.ViewBox.Width / 2) + offsetX); |
||||
|
double top = _currentMousePosition.Y - ((_magnifier.ViewBox.Height / 2) + offsetY); |
||||
|
return new Point(left, top); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region Overrides
|
||||
|
|
||||
|
protected override Visual GetVisualChild(int index) |
||||
|
{ |
||||
|
return _magnifier; |
||||
|
} |
||||
|
|
||||
|
protected override int VisualChildrenCount |
||||
|
{ |
||||
|
get { return 1; } |
||||
|
} |
||||
|
|
||||
|
protected override Size MeasureOverride(Size constraint) |
||||
|
{ |
||||
|
_magnifier.Measure(constraint); |
||||
|
return base.MeasureOverride(constraint); |
||||
|
} |
||||
|
|
||||
|
protected override Size ArrangeOverride(Size finalSize) |
||||
|
{ |
||||
|
double x = _currentMousePosition.X - (_magnifier.DefaultSize.Width / 2); |
||||
|
double y = _currentMousePosition.Y - (_magnifier.DefaultSize.Height / 2); |
||||
|
_magnifier.Arrange(new Rect(x, y, _magnifier.DefaultSize.Width, _magnifier.DefaultSize.Height)); |
||||
|
return base.ArrangeOverride(finalSize); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,98 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Documents; |
||||
|
using System.Windows.Input; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class MagnifierManager : DependencyObject |
||||
|
{ |
||||
|
#region Members
|
||||
|
|
||||
|
private MagnifierAdorner _adorner; |
||||
|
private UIElement _element; |
||||
|
|
||||
|
#endregion //Members
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
public static readonly DependencyProperty CurrentProperty = DependencyProperty.RegisterAttached("Magnifier", typeof(Magnifier), typeof(UIElement), new FrameworkPropertyMetadata(null, OnMagnifierChanged)); |
||||
|
public static void SetMagnifier(UIElement element, Magnifier value) |
||||
|
{ |
||||
|
element.SetValue(CurrentProperty, value); |
||||
|
} |
||||
|
public static Magnifier GetMagnifier(UIElement element) |
||||
|
{ |
||||
|
return (Magnifier)element.GetValue(CurrentProperty); |
||||
|
} |
||||
|
|
||||
|
private static void OnMagnifierChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
UIElement target = d as UIElement; |
||||
|
|
||||
|
if (target == null) |
||||
|
throw new ArgumentException("Magnifier can only be attached to a UIElement."); |
||||
|
|
||||
|
MagnifierManager manager = new MagnifierManager(); |
||||
|
manager.AttachToMagnifier(target, e.NewValue as Magnifier); |
||||
|
} |
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Event Handlers
|
||||
|
|
||||
|
void Element_MouseLeave(object sender, MouseEventArgs e) |
||||
|
{ |
||||
|
HideAdorner(); |
||||
|
} |
||||
|
|
||||
|
void Element_MouseEnter(object sender, MouseEventArgs e) |
||||
|
{ |
||||
|
ShowAdorner(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Handlers
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
private void AttachToMagnifier(UIElement element, Magnifier magnifier) |
||||
|
{ |
||||
|
_element = element; |
||||
|
_element.MouseEnter += Element_MouseEnter; |
||||
|
_element.MouseLeave += Element_MouseLeave; |
||||
|
|
||||
|
magnifier.Target = _element; |
||||
|
|
||||
|
_adorner = new MagnifierAdorner(_element, magnifier); |
||||
|
} |
||||
|
|
||||
|
void ShowAdorner() |
||||
|
{ |
||||
|
VerifyAdornerLayer(); |
||||
|
_adorner.Visibility = Visibility.Visible; |
||||
|
} |
||||
|
|
||||
|
bool VerifyAdornerLayer() |
||||
|
{ |
||||
|
if (_adorner.Parent != null) |
||||
|
return true; |
||||
|
|
||||
|
AdornerLayer layer = AdornerLayer.GetAdornerLayer(_element); |
||||
|
if (layer == null) |
||||
|
return false; |
||||
|
|
||||
|
layer.Add(_adorner); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
void HideAdorner() |
||||
|
{ |
||||
|
if (_adorner.Visibility == Visibility.Visible) |
||||
|
{ |
||||
|
_adorner.Visibility = Visibility.Collapsed; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue