/// <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); }
/// <summary> /// Returns whether or not the given node is inside the rectangle. /// </summary> protected override bool IsInBox(IInputModeContext context, RectD rectangle, INode node) { var nodeOrientedRect = GetRotatedLayout(node); // Create an oriented rectangle with the size of the wrapped bounds and the location and rotation of the node var wrappedBounds = Wrapped.Renderer.GetBoundsProvider(node, Wrapped).GetBounds(context); var orientedRectangle = new OrientedRectangle(0, 0, wrappedBounds.Width, wrappedBounds.Height, nodeOrientedRect.UpX, nodeOrientedRect.UpY); orientedRectangle.SetCenter(node.Layout.GetCenter()); return(rectangle.Intersects(orientedRectangle, 0.01)); }
/// <summary> /// Returns bounds based on the size provided by the wrapped style and the location and rotation of the node. /// </summary> protected override RectD GetBounds(ICanvasContext context, INode node) { var nodeOrientedRect = GetRotatedLayout(node); // Create an oriented rectangle with the size of the wrapped bounds and the location and rotation of the node var wrappedBounds = Wrapped.Renderer.GetBoundsProvider(node, Wrapped).GetBounds(context); var orientedRectangle = new OrientedRectangle(0, 0, wrappedBounds.Width, wrappedBounds.Height, nodeOrientedRect.UpX, nodeOrientedRect.UpY); orientedRectangle.SetCenter(node.Layout.GetCenter()); return(orientedRectangle.GetBounds()); }
/// <summary> /// Returns the current geometry of the given label. /// </summary> public IOrientedRectangle GetGeometry(ILabel label, ILabelModelParameter parameter) { var styleWrapper = GetNodeStyleWrapper(label); var wrappedParameter = GetWrappedParameter(parameter); var orientedRectangle = wrappedParameter.Model.GetGeometry(label, wrappedParameter); var node = label.Owner as INode; if (!UseNodeRotation || node == null || styleWrapper == null || styleWrapper.Angle == 0) { return(orientedRectangle); } var rotatedCenter = styleWrapper.GetRotatedPoint(orientedRectangle.GetCenter(), node, true); var rotatedLayout = styleWrapper.GetRotatedLayout(node); var rectangle = new OrientedRectangle(orientedRectangle); rectangle.Angle += rotatedLayout.GetRadians(); rectangle.SetCenter(rotatedCenter); return(rectangle); }
/// <summary> /// Finds the label model parameter that describes the given label layout best. /// </summary> /// <remarks> /// Sometimes the layout cannot be met exactly, then the nearest location is used. /// </remarks> public ILabelModelParameter FindBestParameter(ILabel label, ILabelModel model, IOrientedRectangle labelLayout) { var wrapperModel = model as RotatableNodeLabelModelDecorator; var styleWrapper = wrapperModel.GetNodeStyleWrapper(label); if (!wrapperModel.UseNodeRotation || styleWrapper == null || styleWrapper.Angle == 0) { return (wrapperModel.CreateWrappingParameter(wrappedFinder.FindBestParameter(label, wrapperModel.Wrapped, labelLayout))); } var node = label.Owner as INode; var rotatedCenter = styleWrapper.GetRotatedPoint(labelLayout.GetCenter(), node, false); var rotatedLayout = styleWrapper.GetRotatedLayout(node); var rectangle = new OrientedRectangle(labelLayout); rectangle.Angle -= rotatedLayout.GetRadians(); rectangle.SetCenter(rotatedCenter); return (wrapperModel.CreateWrappingParameter(wrappedFinder.FindBestParameter(label, wrapperModel.Wrapped, rectangle))); }