using System; using System.Text; using System.Globalization; using System.Collections.Generic; using System.Windows; using System.Windows.Input; using System.Windows.Shapes; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Controls; using System.Windows.Controls.Primitives; namespace SharpVectors.Runtime { /// /// This creates a host for visuals derived from the class. /// /// /// This class provides layout, event handling, and container support for the /// child visual objects. /// public sealed class SvgAnimationLayer : DependencyObject { #region Private Fields private Rect _bounds; private Color _colorText; private Color _colorLink; private Color _colorSelected; private Color _colorHover; private ToolTip _tooltip; private TextBlock _tooltipText; private Transform _displayTransform; private DrawingGroup _wholeDrawing; private DrawingGroup _linksDrawing; // Create a collection of child visual objects. private List _linkObjects; private List _drawObjects; private Drawing _hitVisual; private Drawing _selectedVisual; private SvgAnimator _animator; private SvgDrawingCanvas _drawingCanvas; private Dictionary _visualBrushes; #endregion #region Constructors and Destructor public SvgAnimationLayer(SvgDrawingCanvas drawingCanvas) { _animator = new SvgAnimator(); _drawingCanvas = drawingCanvas; _displayTransform = Transform.Identity; _colorText = Colors.Black; _colorLink = Colors.Blue; _colorSelected = Colors.Red; _colorHover = (Color)ColorConverter.ConvertFromString("#ffa500"); _visualBrushes = new Dictionary(StringComparer.OrdinalIgnoreCase); _drawObjects = new List(); _linkObjects = new List(); // Create a tooltip and set its position. _tooltip = new ToolTip(); _tooltip.Placement = PlacementMode.MousePoint; _tooltip.PlacementRectangle = new Rect(50, 0, 0, 0); _tooltip.HorizontalOffset = 20; _tooltip.VerticalOffset = 20; _tooltipText = new TextBlock(); _tooltipText.Text = String.Empty; _tooltipText.Margin = new Thickness(6, 0, 0, 0); //Create BulletDecorator and set it as the tooltip content. Ellipse bullet = new Ellipse(); bullet.Height = 10; bullet.Width = 10; bullet.Fill = Brushes.LightCyan; BulletDecorator decorator = new BulletDecorator(); decorator.Bullet = bullet; decorator.Margin = new Thickness(0, 0, 10, 0); decorator.Child = _tooltipText; _tooltip.Content = decorator; _tooltip.IsOpen = false; _tooltip.Visibility = Visibility.Hidden; //Finally, set tooltip on this canvas _drawingCanvas.ToolTip = _tooltip; //_drawingCanvas.Background = Brushes.Transparent; } #endregion #region Public Properties public Transform DisplayTransform { get { return _displayTransform; } set { if (value == null) { _displayTransform = new MatrixTransform(Matrix.Identity); } else { _displayTransform = value; } } } #endregion #region Public Methods public void LoadDiagrams(DrawingGroup linkGroups, DrawingGroup wholeGroup) { if (linkGroups == null) { return; } DrawingCollection drawings = linkGroups.Children; if (drawings == null || drawings.Count == 0) { return; } else if (drawings.Count == 1) { DrawingGroup layerGroup = drawings[0] as DrawingGroup; if (layerGroup != null) { string elementId = SvgObject.GetId(layerGroup); if (!String.IsNullOrEmpty(elementId) && String.Equals(elementId, "IndicateLayer", StringComparison.OrdinalIgnoreCase)) { this.LoadLayerDiagrams(layerGroup); _wholeDrawing = wholeGroup; _linksDrawing = linkGroups; return; } } } this.UnloadDiagrams(); for (int i = 0; i < drawings.Count; i++) { DrawingGroup childGroup = drawings[i] as DrawingGroup; if (childGroup != null) { string groupName = SvgLink.GetKey(childGroup); //string groupName = childGroup.GetValue(FrameworkElement.NameProperty) as string; if (String.IsNullOrEmpty(groupName)) { if (childGroup.Children != null && childGroup.Children.Count == 1) { this.AddDrawing(childGroup); } else { throw new InvalidOperationException("Error: The link group is in error."); } } else { if (childGroup.Children != null && childGroup.Children.Count == 1) { this.AddDrawing(childGroup, groupName); } else { throw new InvalidOperationException( String.Format("Error: The link group is in error - {0}", groupName)); } } } } _wholeDrawing = wholeGroup; _linksDrawing = linkGroups; if (_drawingCanvas != null) { _displayTransform = _drawingCanvas.DisplayTransform; } } public void UnloadDiagrams() { _displayTransform = Transform.Identity; _bounds = new Rect(0, 0, 1, 1); //_brushIndex = 0; if (_animator != null) { _animator.Stop(); } this.ClearVisuals(); if (_tooltip != null) { _tooltip.IsOpen = false; _tooltip.Visibility = Visibility.Hidden; } //this.RenderTransform = new TranslateTransform(0, 0); _wholeDrawing = null; _linksDrawing = null; } #endregion #region Public Mouse Methods public bool HandleMouseMove(MouseEventArgs e) { // Retrieve the coordinates of the mouse button event. Point pt = e.GetPosition(_drawingCanvas); Drawing hitVisual = HitTest(pt); if (_selectedVisual != null && hitVisual == _selectedVisual) { _drawingCanvas.Cursor = Cursors.Hand; return true; } string itemName = null; if (hitVisual == null) { if (_hitVisual != null) { itemName = _hitVisual.GetValue(FrameworkElement.NameProperty) as string; if (itemName == null) { _hitVisual = null; return false; } if (_visualBrushes.ContainsKey(itemName) && (_hitVisual != _selectedVisual)) { SolidColorBrush brush = _visualBrushes[itemName] as SolidColorBrush; if (brush != null) { brush.Color = _colorLink; } } _hitVisual = null; } if (_tooltip != null) { _tooltip.IsOpen = false; _tooltip.Visibility = Visibility.Hidden; } return false; } else { _drawingCanvas.Cursor = Cursors.Hand; if (hitVisual == _hitVisual) { return false; } if (_hitVisual != null) { itemName = _hitVisual.GetValue(FrameworkElement.NameProperty) as string; if (itemName == null) { _hitVisual = null; return false; } if (_visualBrushes.ContainsKey(itemName) && (_hitVisual != _selectedVisual)) { SolidColorBrush brush = _visualBrushes[itemName] as SolidColorBrush; if (brush != null) { brush.Color = _colorLink; } } _hitVisual = null; } itemName = hitVisual.GetValue(FrameworkElement.NameProperty) as string; if (itemName == null) { return false; } if (_visualBrushes.ContainsKey(itemName)) { SolidColorBrush brush = _visualBrushes[itemName] as SolidColorBrush; if (brush != null) { brush.Color = _colorHover; } } _hitVisual = hitVisual; string tooltipText = itemName; SvgLinkAction linkAction = SvgLink.GetAction(hitVisual); if (linkAction == SvgLinkAction.LinkTooltip && _tooltip != null && !String.IsNullOrEmpty(tooltipText)) { Rect rectBounds = hitVisual.Bounds; _tooltip.PlacementRectangle = rectBounds; _tooltipText.Text = tooltipText; if (_tooltip.Visibility == Visibility.Hidden) { _tooltip.Visibility = Visibility.Visible; } _tooltip.IsOpen = true; } else { if (_tooltip != null) { _tooltip.IsOpen = false; _tooltip.Visibility = Visibility.Hidden; } } } return true; } public bool HandleMouseDown(MouseButtonEventArgs e) { Point pt = e.GetPosition(_drawingCanvas); Drawing visual = HitTest(pt); if (visual == null) { if (_tooltip != null) { _tooltip.IsOpen = false; _tooltip.Visibility = Visibility.Hidden; } return false; } if (_selectedVisual != null && visual == _selectedVisual) { _drawingCanvas.Cursor = Cursors.Hand; return true; } string itemName = visual.GetValue(FrameworkElement.NameProperty) as string; if (itemName == null) { if (_tooltip != null) { _tooltip.IsOpen = false; _tooltip.Visibility = Visibility.Hidden; } return false; } SolidColorBrush brush = null; if (_visualBrushes.ContainsKey(itemName)) { brush = _visualBrushes[itemName] as SolidColorBrush; if (brush != null) { brush.Color = _colorSelected; } } if (brush == null) { if (_tooltip != null) { _tooltip.IsOpen = false; _tooltip.Visibility = Visibility.Hidden; } return false; } if (_selectedVisual != null) { itemName = _selectedVisual.GetValue(FrameworkElement.NameProperty) as string; if (itemName == null) { return false; } if (_visualBrushes.ContainsKey(itemName)) { brush = _visualBrushes[itemName] as SolidColorBrush; if (brush != null) { brush.Color = _colorLink; } } else { return false; } } _selectedVisual = visual; if (e.ChangedButton == MouseButton.Left) { string brushName = brush.GetValue(FrameworkElement.NameProperty) as string; if (!String.IsNullOrEmpty(brushName)) { SvgLinkAction linkAction = SvgLink.GetAction(visual); if (linkAction == SvgLinkAction.LinkHtml || linkAction == SvgLinkAction.LinkPage) { _animator.Start(brushName, brush); } } } else if (e.ChangedButton == MouseButton.Right) { _animator.Stop(); } return true; } public bool HandleMouseLeave(MouseEventArgs e) { if (_tooltip != null) { _tooltip.IsOpen = false; _tooltip.Visibility = Visibility.Hidden; } if (_hitVisual == null) { return false; } string itemName = _hitVisual.GetValue(FrameworkElement.NameProperty) as string; if (itemName == null) { _hitVisual = null; return false; } if (_visualBrushes.ContainsKey(itemName) && (_hitVisual != _selectedVisual)) { SolidColorBrush brush = _visualBrushes[itemName] as SolidColorBrush; if (brush != null) { brush.Color = _colorLink; } } _hitVisual = null; return true; } #endregion #region Private Methods private void ClearVisuals() { if (_drawObjects != null && _drawObjects.Count != 0) { _drawObjects.Clear(); } if (_linkObjects != null && _linkObjects.Count != 0) { _linkObjects.Clear(); } } private Drawing HitTest(Point pt) { Point ptDisplay = _displayTransform.Transform(pt); for (int i = 0; i < _linkObjects.Count; i++) { Drawing drawing = _linkObjects[i]; if (drawing.Bounds.Contains(ptDisplay)) { return drawing; } } return null; } private void AddDrawing(DrawingGroup group) { } private void AddDrawing(DrawingGroup group, string name) { } private void AddTextDrawing(DrawingGroup group, string name) { bool isHyperlink = false; if (name == "x11201_1_") { isHyperlink = true; } SolidColorBrush textBrush = null; if (name.StartsWith("XMLID_", StringComparison.OrdinalIgnoreCase)) { textBrush = new SolidColorBrush(_colorText); } else { isHyperlink = true; textBrush = new SolidColorBrush(_colorLink); } string brushName = name + "_Brush"; textBrush.SetValue(FrameworkElement.NameProperty, brushName); DrawingCollection drawings = group.Children; int itemCount = drawings != null ? drawings.Count : 0; for (int i = 0; i < itemCount; i++) { DrawingGroup drawing = drawings[i] as DrawingGroup; if (drawing != null) { for (int j = 0; j < drawing.Children.Count; j++) { GlyphRunDrawing glyphDrawing = drawing.Children[j] as GlyphRunDrawing; if (glyphDrawing != null) { glyphDrawing.ForegroundBrush = textBrush; } } } } if (isHyperlink) { _visualBrushes[name] = textBrush; _linkObjects.Add(group); } } private void AddGeometryDrawing(GeometryDrawing drawing) { } private void AddGeometryDrawing(GeometryDrawing drawing, string name) { } private static bool IsValidBounds(Rect rectBounds) { if (rectBounds.IsEmpty || Double.IsNaN(rectBounds.Width) || Double.IsNaN(rectBounds.Height) || Double.IsInfinity(rectBounds.Width) || Double.IsInfinity(rectBounds.Height)) { return false; } return true; } private static bool TryCast(TBase baseObj, out TDerived derivedObj) where TDerived : class, TBase { return (derivedObj = baseObj as TDerived) != null; } private void LoadLayerDiagrams(DrawingGroup layerGroup) { this.UnloadDiagrams(); DrawingCollection drawings = layerGroup.Children; DrawingGroup drawGroup = null; GeometryDrawing drawGeometry = null; for (int i = 0; i < drawings.Count; i++) { Drawing drawing = drawings[i]; if (TryCast(drawing, out drawGroup)) { string groupName = SvgLink.GetKey(drawGroup); if (String.IsNullOrEmpty(groupName)) { groupName = SvgObject.GetId(drawGroup); } //string groupName = childGroup.GetValue(FrameworkElement.NameProperty) as string; if (String.IsNullOrEmpty(groupName)) { LoadLayerGroup(drawGroup); } else { SvgObjectType elementType = SvgObject.GetType(drawGroup); if (elementType == SvgObjectType.Text) { this.AddTextDrawing(drawGroup, groupName); } else { if (drawGroup.Children != null && drawGroup.Children.Count == 1) { this.AddDrawing(drawGroup, groupName); } else { //throw new InvalidOperationException( // String.Format("Error: The link group is in error - {0}", groupName)); } } } } else if (TryCast(drawing, out drawGeometry)) { this.AddGeometryDrawing(drawGeometry); } } if (_drawingCanvas != null) { _displayTransform = _drawingCanvas.DisplayTransform; } } private void LoadLayerGroup(DrawingGroup group) { DrawingCollection drawings = group.Children; DrawingGroup drawGroup = null; GeometryDrawing drawGeometry = null; for (int i = 0; i < drawings.Count; i++) { Drawing drawing = drawings[i]; if (TryCast(drawing, out drawGroup)) { string groupName = SvgLink.GetKey(drawGroup); if (String.IsNullOrEmpty(groupName)) { groupName = SvgObject.GetId(drawGroup); } //string groupName = childGroup.GetValue(FrameworkElement.NameProperty) as string; if (String.IsNullOrEmpty(groupName)) { LoadLayerGroup(drawGroup); } else { SvgObjectType elementType = SvgObject.GetType(drawGroup); if (elementType == SvgObjectType.Text) { this.AddTextDrawing(drawGroup, groupName); } else { if (drawGroup.Children != null && drawGroup.Children.Count == 1) { this.AddDrawing(drawGroup, groupName); } else { //throw new InvalidOperationException( // String.Format("Error: The link group is in error - {0}", groupName)); } } } } else if (TryCast(drawing, out drawGeometry)) { this.AddGeometryDrawing(drawGeometry); } } } #endregion } }