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