// (c) Copyright ESRI. // This source is subject to the Microsoft Public License (Ms-PL). // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. // All other rights reserved. using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using ESRI.ArcGIS.Client.Geometry; namespace ESRI.ArcGIS.Client.Toolkit { /// /// Map Magnifying glass /// public partial class Magnifier : UserControl { FrameworkElement rootElement; bool isActive; /// /// Initializes a new instance of the class. /// public Magnifier() { InitializeComponent(); Layers = bigMap.Layers; ZoomFactor = 2; this.Cursor = Cursors.None; bool isDesignMode = System.ComponentModel.DesignerProperties.GetIsInDesignMode(this);//Note: returns true in Blend but not VS if(!isDesignMode) this.LayoutRoot.Visibility = Visibility.Collapsed; this.MouseLeftButtonUp += new MouseButtonEventHandler(Magnifier_MouseLeftButtonUp); } void Magnifier_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { this.Enabled = false; } /// /// Initializes using the specified map. /// /// The map. [System.Obsolete("Use Map property")] public void Initialize(ESRI.ArcGIS.Client.Map map) { this.Map = map; } private void updateExtent(Envelope parentMapExtent) { bigMap.Extent = parentMapExtent; } private void dragGlass(object sender, MouseEventArgs e) { double x = e.GetPosition(null).X; double y = e.GetPosition(null).Y; Point offset = e.GetPosition(this); ApplyTranslationTransform(offset.X - 85,offset.Y -85); bigMap.SetValue(Canvas.LeftProperty, (- x * ZoomFactor) + 94 ); bigMap.SetValue(Canvas.TopProperty, (- y * ZoomFactor) + 95 ); } private void ApplyTranslationTransform(double x, double y) { Transform renderTransform = this.RenderTransform; TransformGroup group = renderTransform as TransformGroup; MatrixTransform transform2 = renderTransform as MatrixTransform; TranslateTransform transform3 = renderTransform as TranslateTransform; if (transform3 == null) { if (group != null) { if (group.Children.Count > 0) { transform3 = group.Children[group.Children.Count - 1] as TranslateTransform; } if (transform3 == null) { transform3 = new TranslateTransform(); group.Children.Add(transform3); } } else { if (transform2 != null) { Matrix matrix = transform2.Matrix; matrix.OffsetX += x; matrix.OffsetY += y; MatrixTransform transform4 = new MatrixTransform(); transform4.Matrix = matrix; this.RenderTransform = transform4; return; } TransformGroup group2 = new TransformGroup(); transform3 = new TranslateTransform(); if (renderTransform != null) { group2.Children.Add(renderTransform); } group2.Children.Add(transform3); this.RenderTransform = group2; } } transform3.X = x; transform3.Y = y; } /// /// Gets or sets a value indicating whether this is enabled. /// /// true if enabled; otherwise, false. public bool Enabled { get { return isActive; } set { if (value) StartDrag(); else { StopDrag(); } } } private void StopDrag() { isActive = false; this.LayoutRoot.Visibility = Visibility.Collapsed; } private void StartDrag() { isActive = true; this.LayoutRoot.Visibility = Visibility.Visible; SetVisualSize(); magGlass.Opacity = 1; bigScene.Opacity = 1; Dispatcher.BeginInvoke((Action)delegate() { updateExtent(Map.Extent); }); } private void SetVisualSize() { if (this.Visibility == Visibility.Collapsed) return; if (bigMap != null && Map != null) { bool DesignMode; #if SILVERLIGHT DesignMode = System.ComponentModel.DesignerProperties.IsInDesignTool; #else var prop = System.ComponentModel.DesignerProperties.IsInDesignModeProperty; DesignMode = (bool)System.ComponentModel.DependencyPropertyDescriptor.FromProperty(prop, typeof(FrameworkElement)).Metadata.DefaultValue; #endif if(!DesignMode) { var RootVisual = #if SILVERLIGHT Application.Current.RootVisual; #else GetRootVisual(Map); #endif // Get top left screen positon of base map after any scale // transforms have been applied to the base map. Point TopLeft = Map.TransformToVisual(RootVisual).Transform(new Point()); Point BottomRight = Map.TransformToVisual(RootVisual).Transform(new Point(Map.ActualWidth, Map.ActualHeight)); double left = TopLeft.X; double top = TopLeft.Y; double right = BottomRight.X; double bottom = BottomRight.Y; double width = (right - left) * ZoomFactor; double height = (bottom - top) * ZoomFactor; // offset the magnifiers map to align map top left corner // with the base maps top left corner //double left_margin = ((left * ZoomFactor) + Map.Margin.Left); //double top_margin = ((top * ZoomFactor) + Map.Margin.Top); double left_margin = (left * ZoomFactor); double top_margin = (top * ZoomFactor); bigMap.Margin = new Thickness(left_margin, top_margin, 0, 0); // set the width and height of the magnifiers map to the // visual equal of the base maps height after any scale // transform has been applied bigMap.Height = height; bigMap.Width = width; } } } #if !SILVERLIGHT static Visual rootVisual; private static Visual GetRootVisual(UIElement element) { if (Application.Current != null && Application.Current.MainWindow != null) { if (element.IsDescendantOf(Application.Current.MainWindow)) return Application.Current.MainWindow.Content as Visual; } if (rootVisual != null && element.IsDescendantOf(rootVisual)) return rootVisual; DependencyObject dependencyObject = VisualTreeHelper.GetParent(element); if (dependencyObject == null) return element; while (VisualTreeHelper.GetParent(dependencyObject) != null) dependencyObject = VisualTreeHelper.GetParent(dependencyObject); rootVisual = dependencyObject as Visual; return rootVisual; } #endif /// /// Identifies the dependency property. /// public static readonly DependencyProperty LayersProperty = DependencyProperty.RegisterAttached("Layers", typeof(ESRI.ArcGIS.Client.LayerCollection), typeof(Magnifier), new PropertyMetadata(OnLayersPropertyChanged)); /// /// Gets or sets the layers. /// public ESRI.ArcGIS.Client.LayerCollection Layers { get { return (ESRI.ArcGIS.Client.LayerCollection)GetValue(LayersProperty); } set { SetValue(LayersProperty, value); } } private static void OnLayersPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Magnifier m = d as Magnifier; if (m.bigMap != null) m.bigMap.Layers = e.NewValue as LayerCollection; m.SetVisualSize(); } /// /// Gets or sets the zoom factor. /// public double ZoomFactor { get; set; } /// /// Gets or sets the map that this magnifier should magnify on. /// /// The map. public Map Map { get { return (Map)GetValue(MapProperty); } set { SetValue(MapProperty, value); } } /// /// Identifies the dependency property. /// public static readonly DependencyProperty MapProperty = DependencyProperty.Register("Map", typeof(Map), typeof(Magnifier), new PropertyMetadata(null, OnMapPropertyChanged)); private static void OnMapPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Magnifier obj = (Magnifier)d; Map newValue = (Map)e.NewValue; Map oldValue = (Map)e.OldValue; if (oldValue != null) { oldValue.RotationChanged -= obj.Map_RotationChanged; obj.rootElement.MouseMove -= obj.dragGlass; obj.rootElement = null; } if (newValue != null) { newValue.RotationChanged += obj.Map_RotationChanged; if(obj.bigMap != null) obj.bigMap.WrapAround = newValue.WrapAround; obj.rootElement = newValue.Parent as FrameworkElement; if (obj.rootElement != null) obj.rootElement.MouseMove += obj.dragGlass; obj.SetVisualSize(); } } private void Map_RotationChanged(object sender, DependencyPropertyChangedEventArgs e) { if (bigMap == null) return; bigMap.Rotation = (this.FlowDirection == System.Windows.FlowDirection.LeftToRight) ? (double)e.NewValue : -(double)e.NewValue; } } }