Beispiel #1
0
        public static void PrintToFit(GraphAreaBase visual, string description, int margin = 0)
        {
            var pd = new PrintDialog();

            if (pd.ShowDialog() == true)
            {
                visual.SetPrintMode(true, true, margin);

                //store original scale
                var originalScale = visual.LayoutTransform;
                //get selected printer capabilities
                var capabilities = pd.PrintQueue.GetPrintCapabilities(pd.PrintTicket);

                //get scale of the print wrt to screen of WPF visual
                var scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / visual.ActualWidth, capabilities.PageImageableArea.ExtentHeight /
                                     visual.ActualHeight);

                //Transform the Visual to scale
                var group = new TransformGroup();
                group.Children.Add(new ScaleTransform(scale, scale));
                visual.LayoutTransform = group;
                visual.InvalidateArrange();
                visual.UpdateLayout();

                //now print the visual to printer to fit on the one page.
                pd.PrintVisual(visual, description);

                //apply the original transform.
                visual.LayoutTransform = originalScale;
                visual.SetPrintMode(false, true, margin);
            }
        }
Beispiel #2
0
        private static void UpdateCoordinates(GraphAreaBase area, DependencyObject obj, double horizontalChange, double verticalChange, SnapModifierFunc xSnapModifier, SnapModifierFunc ySnapModifier)
        {
            if (double.IsNaN(GraphAreaBase.GetX(obj)))
            {
                GraphAreaBase.SetX(obj, 0, true);
            }
            if (double.IsNaN(GraphAreaBase.GetY(obj)))
            {
                GraphAreaBase.SetY(obj, 0, true);
            }

            //move the object
            var x = GetOriginalX(obj) + horizontalChange;

            if (xSnapModifier != null)
            {
                x = xSnapModifier(area, obj, x);
            }
            GraphAreaBase.SetX(obj, x, true);

            var y = GetOriginalY(obj) + verticalChange;

            if (ySnapModifier != null)
            {
                y = ySnapModifier(area, obj, y);
            }
            GraphAreaBase.SetY(obj, y, true);

            if (GetUpdateEdgesOnMove(obj))
            {
                UpdateVertexEdges(obj as VertexControl);
            }

            //Debug.WriteLine("({0:##0.00000}, {1:##0.00000})", x, y);
        }
Beispiel #3
0
        public static void PrintWithDPI(GraphAreaBase visual, string description, double dpi, int margin = 0)
        {
            var pd = new PrintDialog();

            if (pd.ShowDialog() == true)
            {
                visual.SetPrintMode(true, true, margin);
                //store original scale
                var originalScale = visual.LayoutTransform;
                //get scale from DPI
                var scale = dpi / DEFAULT_DPI;
                //Transform the Visual to scale
                var group = new TransformGroup();
                group.Children.Add(new ScaleTransform(scale, scale));
                visual.LayoutTransform = group;
                //update visual
                visual.InvalidateArrange();
                visual.UpdateLayout();

                //now print the visual to printer to fit on the one page.
                pd.PrintVisual(visual, description);
                //apply the original transform.
                visual.LayoutTransform = originalScale;
                visual.SetPrintMode(false, true, margin);
            }
        }
Beispiel #4
0
        private static void OnDragStarted(object sender, PointerRoutedEventArgs e)
#endif
        {
            var obj = sender as DependencyObject;

            //we are starting the drag
            SetIsDragging(obj, true);

            // Save the position of the mouse to the start position
            var area = GetAreaFromObject(obj);
            var pos  = GetPositionInArea(area, e);

            SetOriginalMouseX(obj, pos.X);
            SetOriginalMouseY(obj, pos.Y);

            // Save the position of the dragged object to its starting position
            SetOriginalX(obj, GraphAreaBase.GetFinalX(obj));
            SetOriginalY(obj, GraphAreaBase.GetFinalY(obj));

            // Save starting position of all tagged elements
            if (GetIsTagged(obj))
            {
                foreach (var item in area.GetAllVertexControls())
                {
                    if (GetIsTagged(item))
                    {
                        SetOriginalX(item, GraphAreaBase.GetFinalX(item));
                        SetOriginalY(item, GraphAreaBase.GetFinalY(item));
                    }
                }
            }

            //capture the mouse
#if WPF
            var element = obj as IInputElement;
            if (element != null)
            {
                element.CaptureMouse();
                element.MouseMove -= OnDragging;
                element.MouseMove += OnDragging;
            }
            //else throw new GX_InvalidDataException("The control must be a descendent of the FrameworkElement or FrameworkContentElement!");
            e.Handled = false;
#elif METRO
            var element = obj as FrameworkElement;
            if (element != null)
            {
                element.CapturePointer(e.Pointer);
                element.PointerMoved += OnDragging;
            }
            e.Handled = true;
#endif
        }
Beispiel #5
0
        //Set pixelformat of image.
        /////!!! private static PixelFormat pixelFormat = PixelFormats.Pbgra32;

        /// <summary>
        /// Method exports the GraphArea to an png image.
        /// </summary>
        /// <param name="surface">GraphArea control</param>
        /// <param name="path">Image destination path</param>
        /// <param name="imgdpi">Optional image DPI parameter</param>
        /// <param name="imgQuality">Optional image quality parameter (for some formats like JPEG)</param>
        public static void ExportToImage(GraphAreaBase surface, Uri path, ImageType itype, bool useZoomControlSurface = false, double imgdpi = DEFAULT_DPI, int imgQuality = 100)
        {
            //TODO
            //Create a render bitmap and push the surface to it

            /*Visual vis = surface;
             * if (useZoomControlSurface)
             * {
             *  if (surface.Parent != null && surface.Parent is IZoomControl)
             *      vis = (surface.Parent as IZoomControl).PresenterVisual;
             *  else if(surface.Parent!=null && surface.Parent is FrameworkElement && (surface.Parent as FrameworkElement).Parent is IZoomControl)
             *      vis = ((surface.Parent as FrameworkElement).Parent as IZoomControl).PresenterVisual;
             * }
             * var renderBitmap =
             *      new RenderTargetBitmap(
             *                      //(int)surface.ActualWidth,
             *                      //(int)surface.ActualHeight,
             *      (int)((vis as UIElement).DesiredSize.Width * (imgdpi / DefaultDPI) + 100),
             *      (int)((vis as UIElement).DesiredSize.Height * (imgdpi / DefaultDPI) + 100),
             *      imgdpi,
             *      imgdpi,
             *      pixelFormat);
             *
             * //Render the graphlayout onto the bitmap.
             * renderBitmap.Render(vis);
             *
             *
             * //Create a file stream for saving image
             * using (FileStream outStream = new FileStream(path.LocalPath, FileMode.Create))
             * {
             *  //Use png encoder for our data
             *  BitmapEncoder encoder;
             *  switch (itype)
             *  {
             *      case ImageType.PNG: encoder = new PngBitmapEncoder();
             *          break;
             *      case ImageType.JPEG: encoder = new JpegBitmapEncoder() { QualityLevel = imgQuality };
             *          break;
             *      case ImageType.BMP: encoder = new BmpBitmapEncoder();
             *          break;
             *      case ImageType.GIF: encoder = new GifBitmapEncoder();
             *          break;
             *      case ImageType.TIFF: encoder = new TiffBitmapEncoder();
             *          break;
             *      default: throw new GX_InvalidDataException("ExportToImage() -> Unknown output image format specified!");
             *  }
             *
             *  //Push the rendered bitmap to it
             *  encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
             *  //Save the data to the stream
             *  encoder.Save(outStream);
             * }*/
        }
Beispiel #6
0
        private static Windows.Foundation.Point GetPositionInArea(GraphAreaBase area, PointerRoutedEventArgs e)
#endif
        {
            if (area != null)
            {
#if WPF
                var pos = e.GetPosition(area);
#elif METRO
                var pos = e.GetCurrentPoint(area as UIElement).Position;
#endif
                return(pos);
            }
            throw new GX_InvalidDataException("DragBehavior.GetPositionInArea() - The input element must be a child of a GraphAreaBase.");
        }
Beispiel #7
0
        private static void OnEdgeDragFinished(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            EdgeControl edgeControl = sender as EdgeControl;

            if (edgeControl == null)
            {
                return;
            }

            GraphAreaBase graphAreaBase = edgeControl.RootArea;

            VertexControl vertexControl = graphAreaBase.GetVertexControlAt(e.GetPosition(graphAreaBase));

            if (vertexControl != null)
            {
                edgeControl.Target = vertexControl;

                if (vertexControl.VertexConnectionPointsList.Count > 0)
                {
                    IVertexConnectionPoint vertexConnectionPoint = vertexControl.GetConnectionPointAt(e.GetPosition(graphAreaBase));

                    var edge = edgeControl.Edge as IGraphXCommonEdge;

                    if (vertexConnectionPoint != null)
                    {
                        edge.TargetConnectionPointId = vertexConnectionPoint.Id;
                    }
                    else
                    {
                        edge.TargetConnectionPointId = null;
                    }
                }

                edgeControl.UpdateEdge();

                var obj = (DependencyObject)sender;
                SetIsDragging(obj, false);
                //obj.ClearValue(OriginalMouseXProperty);
                //obj.ClearValue(OriginalMouseYProperty);
                //obj.ClearValue(OriginalXProperty);
                //obj.ClearValue(OriginalYProperty);

                var element = sender as IInputElement;
                if (element != null)
                {
                    element.MouseMove -= OnVertexDragging;
                    element.ReleaseMouseCapture();
                }
            }
        }
Beispiel #8
0
 public static void ShowPrintPreview(GraphAreaBase surface, string description = "")
 {
     try
     {
         var printDialog = new PrintDialog();
         if (printDialog.ShowDialog() == true)
         {
             printDialog.PrintVisual(surface, description);
         }
     }
     catch (Exception)
     {
         MessageBox.Show("Unexpected exception occured while trying to access default printer. Please ensure that default printer is installed in your OS!");
     }
 }
Beispiel #9
0
        public static void ShowPrintPreview(GraphAreaBase surface, string description = "")
        {
            //TODO

            /* try
             * {
             *   var printDialog = new PrintDialog();
             *   if (printDialog.ShowDialog() == true)
             *   {
             *       printDialog.PrintVisual(surface, description);
             *   }
             * }
             * catch (Exception ex)
             * {
             *   new MessageDialog("Unexpected exception occured while trying to acces default printer. Please ensure that default printer is installed in your OS!").Show();
             * }*/
        }
Beispiel #10
0
        private static GraphAreaBase GetAreaFromObject(object obj)
        {
            GraphAreaBase area = null;

            if (obj is VertexControl)
            {
                area = ((VertexControl)obj).RootArea;
            }
            else if (obj is EdgeControl)
            {
                area = ((EdgeControl)obj).RootArea;
            }
            else if (obj is DependencyObject)
            {
                area = VisualTreeHelperEx.FindAncestorByType((DependencyObject)obj, typeof(GraphAreaBase), false) as GraphAreaBase;
            }

            return(area);
        }
Beispiel #11
0
        /// <summary>
        /// Helper method which calculates estimated image DPI based on the input criterias
        /// </summary>
        /// <param name="vis">GraphArea object</param>
        /// <param name="imgdpi">Desired DPI</param>
        /// <param name="dpiStep">DPI decrease step while estimating</param>
        /// <param name="estPixelCount">Pixel quantity threshold</param>
        public static double CalculateEstimatedDPI(GraphAreaBase vis, double imgdpi, double dpiStep, int estPixelCount)
        {
            bool   result     = false;
            double currentDPI = imgdpi;

            while (!result)
            {
                if (CalulateSize(vis.ContentSize.Size, currentDPI) <= estPixelCount)
                {
                    result = true;
                }
                else
                {
                    currentDPI -= dpiStep;
                }
                if (currentDPI < 0)
                {
                    return(0);
                }
            }
            return(currentDPI);
        }
        private static void UpdateCoordinates(DependencyObject obj, double horizontalChange, double verticalChange)
        {
            if (double.IsNaN(GraphAreaBase.GetX(obj)))
            {
                GraphAreaBase.SetX(obj, 0, true);
            }
            if (double.IsNaN(GraphAreaBase.GetY(obj)))
            {
                GraphAreaBase.SetY(obj, 0, true);
            }

            //move the object
            var x = GraphAreaBase.GetX(obj) + horizontalChange;

            GraphAreaBase.SetX(obj, x, true);
            var y = GraphAreaBase.GetY(obj) + verticalChange;

            GraphAreaBase.SetY(obj, y, true);
            if (GetUpdateEdgesOnMove(obj))
            {
                UpdateVertexEdges(obj as VertexControl);
            }
        }
Beispiel #13
0
        private static RenderTargetBitmap RenderTargetBitmap(GraphAreaBase surface, bool useZoomControlSurface, double imgdpi)
        {
            UIElement vis = surface;

            if (useZoomControlSurface)
            {
                var zoomControl = surface.Parent as IZoomControl;
                if (zoomControl != null)
                {
                    vis = zoomControl.PresenterVisual;
                }
                else
                {
                    var frameworkElement = surface.Parent as FrameworkElement;
                    if (frameworkElement != null && frameworkElement.Parent is IZoomControl)
                    {
                        vis = ((IZoomControl)frameworkElement.Parent).PresenterVisual;
                    }
                }
            }
            var renderBitmap =
                new RenderTargetBitmap(
                    //(int)surface.ActualWidth,
                    //(int)surface.ActualHeight,
                    (int)(vis.DesiredSize.Width * (imgdpi / 96) + 100),
                    (int)(vis.DesiredSize.Height * (imgdpi / 96) + 100),
                    imgdpi,
                    imgdpi,
                    PixelFormat);

            vis.SetValue(Panel.BackgroundProperty, Brushes.White);
            //Render the graphlayout onto the bitmap.
            renderBitmap.Render(vis);

            return(renderBitmap);
        }
Beispiel #14
0
 /// <summary>
 /// Get control position on the GraphArea panel in attached coords X and Y (GraphX type version)
 /// </summary>
 /// <param name="final"></param>
 /// <param name="round"></param>
 internal Measure.Point GetPositionGraphX(bool final = false, bool round = false)
 {
     return(round ? new Measure.Point(final ? (int)GraphAreaBase.GetFinalX(this) : (int)GraphAreaBase.GetX(this), final ? (int)GraphAreaBase.GetFinalY(this) : (int)GraphAreaBase.GetY(this)) : new Measure.Point(final ? GraphAreaBase.GetFinalX(this) : GraphAreaBase.GetX(this), final ? GraphAreaBase.GetFinalY(this) : GraphAreaBase.GetY(this)));
 }
Beispiel #15
0
 /// <summary>
 /// Get control position on the GraphArea panel in attached coords X and Y
 /// </summary>
 /// <param name="final"></param>
 /// <param name="round"></param>
 public Point GetPosition(bool final = false, bool round = false)
 {
     return(round ? new Point(final ? (int)GraphAreaBase.GetFinalX(this) : (int)GraphAreaBase.GetX(this), final ? (int)GraphAreaBase.GetFinalY(this) : (int)GraphAreaBase.GetY(this)) : new Point(final ? GraphAreaBase.GetFinalX(this) : GraphAreaBase.GetX(this), final ? GraphAreaBase.GetFinalY(this) : GraphAreaBase.GetY(this)));
 }
Beispiel #16
0
 public void SetPosition(double x, double y, bool alsoFinal = true)
 {
     GraphAreaBase.SetX(this, x, alsoFinal);
     GraphAreaBase.SetY(this, y, alsoFinal);
 }
Beispiel #17
0
 /// <summary>
 /// Set attached coordinates X and Y
 /// </summary>
 /// <param name="pt"></param>
 /// <param name="alsoFinal"></param>
 public void SetPosition(Point pt, bool alsoFinal = true)
 {
     GraphAreaBase.SetX(this, pt.X, alsoFinal);
     GraphAreaBase.SetY(this, pt.Y, alsoFinal);
 }
Beispiel #18
0
        /// <summary>
        /// Method exports the GraphArea to an png image.
        /// </summary>
        /// <param name="surface">GraphArea control</param>
        /// <param name="path">Image destination path</param>
        /// <param name="useZoomControlSurface"></param>
        /// <param name="imgdpi">Optional image DPI parameter</param>
        /// <param name="imgQuality">Optional image quality parameter (for some formats like JPEG)</param>
        /// <param name="itype"></param>
        public static void ExportToImage(GraphAreaBase surface, Uri path, ImageType itype, bool useZoomControlSurface = false, double imgdpi = DEFAULT_DPI, int imgQuality = 100)
        {
            if (!useZoomControlSurface)
            {
                surface.SetPrintMode(true, true, 100);
            }
            //Create a render bitmap and push the surface to it
            UIElement vis = surface;

            if (useZoomControlSurface)
            {
                var zoomControl = surface.Parent as IZoomControl;
                if (zoomControl != null)
                {
                    vis = zoomControl.PresenterVisual;
                }
                else
                {
                    var frameworkElement = surface.Parent as FrameworkElement;
                    if (frameworkElement != null && frameworkElement.Parent is IZoomControl)
                    {
                        vis = ((IZoomControl)frameworkElement.Parent).PresenterVisual;
                    }
                }
            }



            var renderBitmap =
                new RenderTargetBitmap(
                    (int)(vis.DesiredSize.Width * (imgdpi / DEFAULT_DPI) + 100),
                    (int)(vis.DesiredSize.Height * (imgdpi / DEFAULT_DPI) + 100),
                    imgdpi,
                    imgdpi,
                    PixelFormat);

            //Render the graphlayout onto the bitmap.
            renderBitmap.Render(vis);


            //Create a file stream for saving image
            using (FileStream outStream = new FileStream(path.LocalPath, FileMode.Create))
            {
                //Use png encoder for our data
                BitmapEncoder encoder;
                switch (itype)
                {
                case ImageType.PNG: encoder = new PngBitmapEncoder();
                    break;

                case ImageType.JPEG: encoder = new JpegBitmapEncoder()
                {
                        QualityLevel = imgQuality
                };
                    break;

                case ImageType.BMP: encoder = new BmpBitmapEncoder();
                    break;

                case ImageType.GIF: encoder = new GifBitmapEncoder();
                    break;

                case ImageType.TIFF: encoder = new TiffBitmapEncoder();
                    break;

                default: throw new GX_InvalidDataException("ExportToImage() -> Unknown output image format specified!");
                }

                //Push the rendered bitmap to it
                encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
                //Save the data to the stream
                encoder.Save(outStream);
            }
            renderBitmap.Clear();
            renderBitmap = null;
            //due to mem leak in wpf :(
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            if (!useZoomControlSurface)
            {
                surface.SetPrintMode(false, true, 100);
            }
        }
Beispiel #19
0
        private static void OnDragging(object sender, PointerRoutedEventArgs e)
#endif
        {
            var obj = sender as DependencyObject;

            if (!GetIsDragging(obj))
            {
                return;
            }

            var area = GetAreaFromObject(obj);
            var pos  = GetPositionInArea(area, e);

            double horizontalChange = pos.X - GetOriginalMouseX(obj);
            double verticalChange   = pos.Y - GetOriginalMouseY(obj);

            // Determine whether to use snapping
            bool snap           = GetIsSnappingPredicate(obj)(obj);
            bool individualSnap = false;
            // Snap modifier functions to apply to the primary dragged object
            SnapModifierFunc snapXMod = null;
            SnapModifierFunc snapYMod = null;
            // Snap modifier functions to apply to other dragged objects if they snap individually instead of moving
            // the same amounts as the primary object.
            SnapModifierFunc individualSnapXMod = null;
            SnapModifierFunc individualSnapYMod = null;

            if (snap)
            {
                snapXMod = GetXSnapModifier(obj);
                snapYMod = GetYSnapModifier(obj);
                // If objects snap to grid individually instead of moving the same amount as the primary dragged object,
                // use the same snap modifier on each individual object.
                individualSnap = GetIsIndividualSnappingPredicate(obj)(obj);
                if (individualSnap)
                {
                    individualSnapXMod = snapXMod;
                    individualSnapYMod = snapYMod;
                }
            }

            if (GetIsTagged(obj))
            {
                // When the dragged item is a tagged item, we could be dragging a group of objects. If the dragged object is a vertex, it's
                // automatically the primary object of the drag. If the dragged object is an edge, prefer the source vertex, but accept the
                // target vertex as the primary object of the drag and start with that.
                var primaryDragVertex = obj as VertexControl;
                if (primaryDragVertex == null)
                {
                    var ec = obj as EdgeControl;
                    if (ec != null)
                    {
                        primaryDragVertex = ec.Source ?? ec.Target;
                    }

                    if (primaryDragVertex == null)
                    {
                        Debug.WriteLine("OnDragging() -> Tagged and dragged the wrong object?");
                        return;
                    }
                }
                UpdateCoordinates(area, primaryDragVertex, horizontalChange, verticalChange, snapXMod, snapYMod);

                if (!individualSnap)
                {
                    // When dragging groups of objects that all move the same amount (not snapping individually, but tracking with
                    // the movement of the primary dragged object), deterrmine how much offset the primary dragged object experienced
                    // and use that offset for the rest.
                    horizontalChange = GraphAreaBase.GetFinalX(primaryDragVertex) - GetOriginalX(primaryDragVertex);
                    verticalChange   = GraphAreaBase.GetFinalY(primaryDragVertex) - GetOriginalY(primaryDragVertex);
                }

                foreach (var item in area.GetAllVertexControls())
                {
                    if (!ReferenceEquals(item, primaryDragVertex) && GetIsTagged(item))
                    {
                        UpdateCoordinates(area, item, horizontalChange, verticalChange, individualSnapXMod, individualSnapYMod);
                    }
                }
            }
            else
            {
                UpdateCoordinates(area, obj, horizontalChange, verticalChange, snapXMod, snapYMod);
            }
            e.Handled = true;
        }
Beispiel #20
0
 private static Point GetPositionInArea(GraphAreaBase area, System.Windows.Input.MouseEventArgs e)
Beispiel #21
0
        /// <summary>
        /// Create and apply edge path using calculated ER parameters stored in edge
        /// </summary>
        /// <param name="useCurrentCoords">Use current vertices coordinates or final coorfinates (for.ex if move animation is active final coords will be its destination)</param>
        /// <param name="externalRoutingPoints">Provided custom routing points will be used instead of stored ones.</param>
        /// <param name="updateLabel">Should edge label be updated in this pass</param>
        public virtual void PrepareEdgePath(bool useCurrentCoords = false, Measure.Point[] externalRoutingPoints = null, bool updateLabel = true)
        {
            //do not calculate invisible edges
            if ((Visibility != Visibility.Visible && !IsHiddenEdgesUpdated) && Source == null || Target == null || ManualDrawing || !IsTemplateLoaded)
            {
                return;
            }

            #region Get the inputs
            //get the size of the source
            var sourceSize = new Size
            {
                Width  = Source.ActualWidth,
                Height = Source.ActualHeight
            };
            if (CustomHelper.IsInDesignMode(this))
            {
                sourceSize = new Size(80, 20);
            }

            //get the position center of the source
            var sourcePos = new Point
            {
                X = (useCurrentCoords ? GraphAreaBase.GetX(Source) : GraphAreaBase.GetFinalX(Source)) + sourceSize.Width * .5,
                Y = (useCurrentCoords ? GraphAreaBase.GetY(Source) : GraphAreaBase.GetFinalY(Source)) + sourceSize.Height * .5
            };

            //get the size of the target
            var targetSize = new Size
            {
                Width  = Target.ActualWidth,
                Height = Target.ActualHeight
            };
            if (CustomHelper.IsInDesignMode(this))
            {
                targetSize = new Size(80, 20);
            }

            //get the position center of the target
            var targetPos = new Point
            {
                X = (useCurrentCoords ? GraphAreaBase.GetX(Target) : GraphAreaBase.GetFinalX(Target)) + targetSize.Width * .5,
                Y = (useCurrentCoords ? GraphAreaBase.GetY(Target) : GraphAreaBase.GetFinalY(Target)) + targetSize.Height * .5
            };

            var routedEdge = Edge as IRoutingInfo;
            if (routedEdge == null)
            {
                throw new GX_InvalidDataException("Edge must implement IRoutingInfo interface");
            }

            //get the route informations
            var routeInformation = externalRoutingPoints ?? routedEdge.RoutingPoints;

            // Get the TopLeft position of the Source Vertex.
            var sourcePos1 = new Point
            {
                X = (useCurrentCoords ? GraphAreaBase.GetX(Source) : GraphAreaBase.GetFinalX(Source)),
                Y = (useCurrentCoords ? GraphAreaBase.GetY(Source) : GraphAreaBase.GetFinalY(Source))
            };
            // Get the TopLeft position of the Target Vertex.
            var targetPos1 = new Point
            {
                X = (useCurrentCoords ? GraphAreaBase.GetX(Target) : GraphAreaBase.GetFinalX(Target)),
                Y = (useCurrentCoords ? GraphAreaBase.GetY(Target) : GraphAreaBase.GetFinalY(Target))
            };

            var hasEpSource = _edgePointerForSource != null;
            var hasEpTarget = _edgePointerForTarget != null;
            #endregion

            //if self looped edge
            if (IsSelfLooped)
            {
                PrepareSelfLoopedEdge(sourcePos1);
                return;
            }

            //check if we have some edge route data
            var hasRouteInfo = routeInformation != null && routeInformation.Length > 1;

            //calculate source and target edge attach points
            if (RootArea != null && !hasRouteInfo && RootArea.EnableParallelEdges && ParallelEdgeOffset != 0)
            {
                sourcePos = GetParallelOffset(Source, Target, ParallelEdgeOffset);
                targetPos = GetParallelOffset(Target, Source, -ParallelEdgeOffset);
            }

            /* Rectangular shapes implementation by bleibold */

            var   gEdge = Edge as IGraphXCommonEdge;
            Point p1;
            Point p2;

            //calculate edge source (p1) and target (p2) endpoints based on different settings
            if (gEdge != null && gEdge.SourceConnectionPointId.HasValue)
            {
                var sourceCp = Source.GetConnectionPointById(gEdge.SourceConnectionPointId.Value, true);
                if (sourceCp == null)
                {
                    throw new GX_ObjectNotFoundException(string.Format("Can't find source vertex VCP by edge source connection point Id({1}) : {0}", Source, gEdge.SourceConnectionPointId));
                }
                if (sourceCp.Shape == VertexShape.None)
                {
                    p1 = sourceCp.RectangularSize.Center();
                }
                else
                {
                    var targetCpPos = gEdge.TargetConnectionPointId.HasValue ? Target.GetConnectionPointById(gEdge.TargetConnectionPointId.Value, true).RectangularSize.Center() : (hasRouteInfo ? routeInformation[1].ToWindows() : (targetPos));
                    p1 = GeometryHelper.GetEdgeEndpoint(sourceCp.RectangularSize.Center(), sourceCp.RectangularSize, targetCpPos, sourceCp.Shape);
                }
            }
            else
            {
                p1 = GeometryHelper.GetEdgeEndpoint(sourcePos, new SysRect(sourcePos1, sourceSize), (hasRouteInfo ? routeInformation[1].ToWindows() : (targetPos)), Source.VertexShape);
            }

            if (gEdge != null && gEdge.TargetConnectionPointId.HasValue)
            {
                var targetCp = Target.GetConnectionPointById(gEdge.TargetConnectionPointId.Value, true);
                if (targetCp == null)
                {
                    throw new GX_ObjectNotFoundException(string.Format("Can't find target vertex VCP by edge target connection point Id({1}) : {0}", Target, gEdge.TargetConnectionPointId));
                }
                if (targetCp.Shape == VertexShape.None)
                {
                    p2 = targetCp.RectangularSize.Center();
                }
                else
                {
                    var sourceCpPos = gEdge.SourceConnectionPointId.HasValue ? Source.GetConnectionPointById(gEdge.SourceConnectionPointId.Value, true).RectangularSize.Center() : hasRouteInfo ? routeInformation[routeInformation.Length - 2].ToWindows() : (sourcePos);
                    p2 = GeometryHelper.GetEdgeEndpoint(targetCp.RectangularSize.Center(), targetCp.RectangularSize, sourceCpPos, targetCp.Shape);
                }
            }
            else
            {
                p2 = GeometryHelper.GetEdgeEndpoint(targetPos, new SysRect(targetPos1, targetSize), hasRouteInfo ? routeInformation[routeInformation.Length - 2].ToWindows() : (sourcePos), Target.VertexShape);
            }

            SourceConnectionPoint = p1;
            TargetConnectionPoint = p2;

            _linegeometry = new PathGeometry(); PathFigure lineFigure;

            //if we have route and route consist of 2 or more points
            if (RootArea != null && hasRouteInfo)
            {
                //replace start and end points with accurate ones
                var routePoints = routeInformation.ToWindows().ToList();
                routePoints.Remove(routePoints.First());
                routePoints.Remove(routePoints.Last());
                routePoints.Insert(0, p1);
                routePoints.Add(p2);

                if (RootArea.EdgeCurvingEnabled)
                {
                    var oPolyLineSegment = GeometryHelper.GetCurveThroughPoints(routePoints.ToArray(), 0.5, RootArea.EdgeCurvingTolerance);

                    if (hasEpTarget)
                    {
                        UpdateTargetEpData(oPolyLineSegment.Points[oPolyLineSegment.Points.Count - 1], oPolyLineSegment.Points[oPolyLineSegment.Points.Count - 2]);
                        oPolyLineSegment.Points.RemoveAt(oPolyLineSegment.Points.Count - 1);
                    }
                    if (hasEpSource)
                    {
                        UpdateSourceEpData(oPolyLineSegment.Points.First(), oPolyLineSegment.Points[1]);
                    }

                    lineFigure = GeometryHelper.GetPathFigureFromPathSegments(routePoints[0], true, true, oPolyLineSegment);
#if WPF
                    //freeze and create resulting geometry
                    GeometryHelper.TryFreeze(oPolyLineSegment);
#endif
                }
                else
                {
                    if (hasEpSource)
                    {
                        UpdateSourceEpData(routePoints.First(), routePoints[1]);
                    }
                    if (hasEpTarget)
                    {
                        routePoints[routePoints.Count - 1] = routePoints[routePoints.Count - 1].Subtract(UpdateTargetEpData(p2, routePoints[routePoints.Count - 2]));
                    }

                    var pcol = new PointCollection();
                    foreach (var item in routePoints)
                    {
                        pcol.Add(item);
                    }

                    lineFigure = new PathFigure {
                        StartPoint = p1, Segments = new PathSegmentCollection {
                            new PolyLineSegment {
                                Points = pcol
                            }
                        }, IsClosed = false
                    };
                }
            }
            else // no route defined
            {
                if (hasEpSource)
                {
                    UpdateSourceEpData(p1, p2);
                }
                if (hasEpTarget)
                {
                    p2 = p2.Subtract(UpdateTargetEpData(p2, p1));
                }

                lineFigure = new PathFigure {
                    StartPoint = p1, Segments = new PathSegmentCollection {
                        new LineSegment()
                        {
                            Point = p2
                        }
                    }, IsClosed = false
                };
            }
            ((PathGeometry)_linegeometry).Figures.Add(lineFigure);
#if WPF
            GeometryHelper.TryFreeze(lineFigure);
            GeometryHelper.TryFreeze(_linegeometry);
#endif
            if (ShowLabel && _edgeLabelControl != null && _updateLabelPosition && updateLabel)
            {
                _edgeLabelControl.UpdatePosition();
            }
        }
Beispiel #22
0
        /// <summary>
        /// Automaticaly update edge label position
        /// </summary>
        public virtual void UpdatePosition()
        {
            if (double.IsNaN(DesiredSize.Width) || DesiredSize.Width == 0)
            {
                return;
            }

            if (EdgeControl == null)
            {
                return;
            }
            if (EdgeControl.Source == null || EdgeControl.Target == null)
            {
                Debug.WriteLine("EdgeLabelControl_LayoutUpdated() -> Got empty edgecontrol!");
                return;
            }
            //if hidden
            if (Visibility != Visibility.Visible)
            {
                return;
            }

            if (EdgeControl.IsSelfLooped)
            {
                var idesiredSize = DesiredSize;
                var pt           = EdgeControl.Source.GetCenterPosition();
                SetSelfLoopedSize(pt, idesiredSize);
                Arrange(LastKnownRectSize);
                return;
            }

            var p1 = EdgeControl.SourceConnectionPoint.GetValueOrDefault();
            var p2 = EdgeControl.TargetConnectionPoint.GetValueOrDefault();

            double edgeLength  = 0;
            var    routingInfo = EdgeControl.Edge as IRoutingInfo;

            if (routingInfo != null)
            {
                var routePoints = routingInfo.RoutingPoints == null ? null : routingInfo.RoutingPoints.ToWindows();

                if (routePoints == null || routePoints.Length == 0)
                {
                    // the edge is a single segment (p1,p2)
                    edgeLength = GetLabelDistance(MathHelper.GetDistanceBetweenPoints(p1, p2));
                }
                else
                {
                    // the edge has one or more segments
                    // compute the total length of all the segments
                    edgeLength = 0;
                    var rplen = routePoints.Length;
                    for (var i = 0; i <= rplen; ++i)
                    {
                        if (i == 0)
                        {
                            edgeLength += MathHelper.GetDistanceBetweenPoints(p1, routePoints[0]);
                        }
                        else if (i == rplen)
                        {
                            edgeLength += MathHelper.GetDistanceBetweenPoints(routePoints[rplen - 1], p2);
                        }
                        else
                        {
                            edgeLength += MathHelper.GetDistanceBetweenPoints(routePoints[i - 1], routePoints[i]);
                        }
                    }
                    // find the line segment where the half distance is located
                    edgeLength = GetLabelDistance(edgeLength);
                    var newp1 = p1;
                    var newp2 = p2;
                    for (var i = 0; i <= rplen; ++i)
                    {
                        double lengthOfSegment;
                        if (i == 0)
                        {
                            lengthOfSegment = MathHelper.GetDistanceBetweenPoints(newp1 = p1, newp2 = routePoints[0]);
                        }
                        else if (i == rplen)
                        {
                            lengthOfSegment = MathHelper.GetDistanceBetweenPoints(newp1 = routePoints[rplen - 1], newp2 = p2);
                        }
                        else
                        {
                            lengthOfSegment = MathHelper.GetDistanceBetweenPoints(newp1 = routePoints[i - 1], newp2 = routePoints[i]);
                        }
                        if (lengthOfSegment >= edgeLength)
                        {
                            break;
                        }
                        edgeLength -= lengthOfSegment;
                    }
                    // redefine our edge points
                    p1 = newp1;
                    p2 = newp2;
                }
            }
            // The label control should be laid out on a rectangle, in the middle of the edge
            var  angleBetweenPoints = MathHelper.GetAngleBetweenPoints(p1, p2);
            var  desiredSize        = DesiredSize;
            bool flipAxis           = p1.X > p2.X; // Flip axis if source is "after" target

            ApplyLabelHorizontalOffset(edgeLength, LabelHorizontalOffset);

            // Calculate the center point of the edge
            var centerPoint = new Point(p1.X + edgeLength * Math.Cos(angleBetweenPoints), p1.Y - edgeLength * Math.Sin(angleBetweenPoints));

            if (AlignToEdge)
            {
                // If we're aligning labels to the edges make sure add the label vertical offset
                var yEdgeOffset = LabelVerticalOffset;
                if (FlipOnRotation && flipAxis && !EdgeControl.IsParallel) // If we've flipped axis, move the offset to the other side of the edge
                {
                    yEdgeOffset = -yEdgeOffset;
                }

                // Adjust offset for rotation. Remember, the offset is perpendicular from the edge tangent.
                // Slap on 90 degrees to the angle between the points, to get the direction of the offset.
                centerPoint.Y -= yEdgeOffset * Math.Sin(angleBetweenPoints + Math.PI / 2);
                centerPoint.X += yEdgeOffset * Math.Cos(angleBetweenPoints + Math.PI / 2);

                // Angle is in degrees
                Angle = -angleBetweenPoints * 180 / Math.PI;
                if (flipAxis)
                {
                    Angle += 180; // Reorient the label so that it's always "pointing north"
                }
            }

            UpdateFinalPosition(centerPoint, desiredSize);

            #if METRO
            GraphAreaBase.SetX(this, LastKnownRectSize.X, true);
            GraphAreaBase.SetY(this, LastKnownRectSize.Y, true);
            #else
            Arrange(LastKnownRectSize);
            #endif
        }