/// <summary> /// Converts the given <see cref="OrientedRectangle"/> from the world into the view coordinate space. /// </summary> internal static void WorldToIntermediateCoordinates(ICanvasContext context, OrientedRectangle rect) { var anchor = new PointD(rect.Anchor); var anchorAndUp = anchor + rect.GetUp(); var renderContext = context as IRenderContext ?? context.Lookup(typeof(IRenderContext)) as IRenderContext; if (renderContext != null) { anchor = renderContext.WorldToIntermediateCoordinates(anchor); anchorAndUp = renderContext.WorldToIntermediateCoordinates(anchorAndUp); } else { var cc = context.Lookup(typeof(CanvasControl)) as CanvasControl; if (cc != null) { anchor = cc.WorldToIntermediateCoordinates(anchor); anchorAndUp = cc.WorldToIntermediateCoordinates(anchorAndUp); } else { // too bad - infer trivial scale matrix anchor *= context.Zoom; anchorAndUp *= context.Zoom; } } rect.SetUpVector((anchorAndUp - anchor).Normalized); rect.SetAnchor(anchor); rect.Width *= context.Zoom; rect.Height *= context.Zoom; }
/// <summary> /// For the given parameter, calculate the actual geometry of the specified label in absolute world coordinates. /// </summary> /// <remarks>The actual position is calculated from the <see cref="MyNodeLabelModelParameter.Ratio"/> specified in the parameter as /// the counterclock-wise angle on the label owner's circumference. Note that we also rotate the label layout itself accordingly.</remarks> public IOrientedRectangle GetGeometry(ILabel label, ILabelModelParameter parameter) { var modelParameter = parameter as MyNodeLabelModelParameter; var ownerNode = label.Owner as INode; if (modelParameter != null && ownerNode != null) { //If we have a matching parameter and a node as owner, calculate the angle for the label position and the matchin rotation of the label layout box itself. var center = ownerNode.Layout.GetCenter(); var radius = Math.Max(ownerNode.Layout.Width, ownerNode.Layout.Height) * 0.5d; var ratio = modelParameter.Ratio; double angle = ratio * Math.PI * 2; double x = Math.Sin(angle); double y = Math.Cos(angle); PointD up = new PointD(-y, x); OrientedRectangle result = new OrientedRectangle(); result.SetUpVector(up); result.Size = label.PreferredSize; result.SetCenter(center + (offset + radius + label.PreferredSize.Height * 0.5d) * up); return(result); } else { return(OrientedRectangle.Empty); } }
public IOrientedRectangle GetGeometry(ILabel label, ILabelModelParameter parameter) { var php = parameter as PoolHeaderParameter; INode owner = (INode)label.Owner; if (php == null || owner == null) { return(null); } ITable table = owner.Lookup <ITable>(); InsetsD insets = table != null && table.Insets != InsetsD.Empty ? table.Insets : new InsetsD(0); var orientedRectangle = new OrientedRectangle(); orientedRectangle.Resize(label.PreferredSize); switch (php.Side) { case 0: // North orientedRectangle.SetUpVector(0, -1); orientedRectangle.SetCenter(new PointD(owner.Layout.X + owner.Layout.Width / 2, owner.Layout.Y + insets.Top / 2)); break; case 1: // East orientedRectangle.SetUpVector(1, 0); orientedRectangle.SetCenter(new PointD(owner.Layout.GetMaxX() - insets.Right / 2, owner.Layout.Y + owner.Layout.Height / 2)); break; case 2: // South orientedRectangle.SetUpVector(0, -1); orientedRectangle.SetCenter(new PointD(owner.Layout.X + owner.Layout.Width / 2, owner.Layout.GetMaxY() - insets.Bottom / 2)); break; case 3: // West default: orientedRectangle.SetUpVector(-1, 0); orientedRectangle.SetCenter(new PointD(owner.Layout.X + insets.Left / 2, owner.Layout.Y + owner.Layout.Height / 2)); break; } return(orientedRectangle); }
/// <summary> /// Updates the layout in the cache. /// </summary> public void UpdateCache(RectD layout) { if (layout.Equals(cachedLayout) && upVector.Equals(cachedOrientedRect.GetUp())) { return; } cachedLayout = layout; cachedOrientedRect.SetUpVector(upVector.X, upVector.Y); cachedOrientedRect.Width = Width; cachedOrientedRect.Height = Height; cachedOrientedRect.SetCenter(cachedLayout.Center); }
///<inheritdoc/> public IOrientedRectangle GetGeometry(ILabel label, ILabelModelParameter parameter) { OrientedRectangle geometry = new OrientedRectangle(0, 0, 10, 10); IEdge edge = (IEdge)label.Owner; if (edge == null) { geometry.Width = -1; geometry.Height = -1; return(geometry); } SliderParameter sliderParameter = (SliderParameter)parameter; SizeD preferredSize = label.PreferredSize; geometry.Width = preferredSize.Width; geometry.Height = preferredSize.Height; geometry.SetUpVector(upX, upY); sliderParameter.SetAnchor(this, edge, geometry); return(geometry); }
public Visual UpdateSelectionVisual(IRenderContext context, Visual oldVisual, IOrientedRectangle layout) { var container = oldVisual as VisualGroup; if (container != null && container.Children.Count == 1) { var visual = container.Children[0] as FrameworkElement; if (visual != null) { Transform transform = context.IntermediateTransform; container.Transform = transform; var anchor = layout.GetAnchorLocation(); var anchorAndUp = anchor + layout.GetUp(); anchor = context.WorldToIntermediateCoordinates(anchor); anchorAndUp = context.WorldToIntermediateCoordinates(anchorAndUp); var or = new OrientedRectangle(); or.SetUpVector((anchorAndUp - anchor).Normalized); or.SetAnchor(anchor); or.Width = layout.Width * context.Zoom; or.Height = layout.Height * context.Zoom; visual.Width = or.Width; visual.Height = or.Height; visual.SetCanvasArrangeRect(new Rect(0, 0, or.Width, or.Height)); ArrangeByLayout(context, visual, or, false); if (!container.IsMeasureValid) { container.Arrange(new Rect(0, 0, or.Width, or.Height)); } return(container); } } return(CreateSelectionVisual(context, layout)); }
protected override VisualGroup CreateVisual(IRenderContext context, ILabel label) { // Updates the dummy label which is internally used for rendering with the properties of the given label. UpdateDummyLabel(context, label); // creates the container for the visual and sets a transform for view coordinates var container = new VisualGroup(); var toViewTransform = context.WorldTransform.Clone(); toViewTransform.Invert(); // ReSharper disable once PossibleUnintendedReferenceComparison if (container.Transform != toViewTransform) { container.Transform = toViewTransform; } var creator = InnerLabelStyle.Renderer.GetVisualCreator(dummyLabel, InnerLabelStyle); // create a new IRenderContext with a zoom of 1 // TODO: Projections var innerContext = new RenderContext(context.Graphics, context.CanvasControl) { ViewTransform = context.ViewTransform, WorldTransform = context.WorldTransform, Zoom = 1 }; //The wrapped style should always think it's rendering with zoom level 1 var visual = creator.CreateVisual(innerContext); if (visual == null) { return(container); } // add the created visual to the container container.Children.Add(visual); IGraphSelection selection = context.CanvasControl != null?context.CanvasControl.Lookup <IGraphSelection>() : null; bool selected = selection != null && selection.IsSelected(label); // if the label is selected, add the selection visualization, too. if (selected) { //The selection descriptor performs its own calculation in the view coordinate system, so //the size and the position of the visualization would be wrong and need to be converted back into world //coordinates var layout = dummyLabel.GetLayout(); var p1 = context.CanvasControl.ToWorldCoordinates(layout.GetAnchorLocation()); var selectionLayout = new OrientedRectangle { Anchor = p1, Width = layout.Width / context.Zoom, Height = layout.Height / context.Zoom }; selectionLayout.SetUpVector(layout.UpX, layout.UpY); var selectionVisual = new OrientedRectangleIndicatorInstaller().Template; container.Children.Add(selectionVisual); } return(container); }