public override List <WidgetAndPosition> FindDescendants(IEnumerable <string> namesToSearchFor, List <WidgetAndPosition> foundChildren, RectangleDouble touchingBounds, SearchType seachType, bool allowInvalidItems = true) { foreach (var child in Scene.Children) { string object3DName = child.Name; if (object3DName == null && child.MeshPath != null) { object3DName = Path.GetFileName(child.MeshPath); } bool nameFound = false; foreach (var nameToSearchFor in namesToSearchFor) { if (seachType == SearchType.Exact) { if (object3DName == nameToSearchFor) { nameFound = true; } } else { if (nameToSearchFor == "" || object3DName.Contains(nameToSearchFor)) { nameFound = true; } } } if (nameFound) { AxisAlignedBoundingBox bounds = child.GetBVHData().GetAxisAlignedBoundingBox(); RectangleDouble screenBoundsOfObject3D = RectangleDouble.ZeroIntersection; for (int i = 0; i < 4; i++) { screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetTopCorner(i))); screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetBottomCorner(i))); } if (touchingBounds.IsTouching(screenBoundsOfObject3D)) { Vector3 renderPosition = bounds.Center; Vector2 objectCenterScreenSpace = this.World.GetScreenPosition(renderPosition); Point2D screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y); foundChildren.Add(new WidgetAndPosition(this, screenPositionOfObject3D, object3DName)); } } } return(base.FindDescendants(namesToSearchFor, foundChildren, touchingBounds, seachType, allowInvalidItems)); }
public RectangleDouble GetTotalBounds() { RectangleDouble totalBounds = GetTrackBounds(); totalBounds.ExpandToInclude(GetThumbBounds()); if (sliderAttachedTo.sliderTextWidget.Text != "") { totalBounds.ExpandToInclude(sliderAttachedTo.sliderTextWidget.BoundsRelativeToParent); } return(totalBounds); }
public RectangleDouble GetTotalBounds() { RectangleDouble totalBounds = GetTrackBounds(); totalBounds.ExpandToInclude(GetThumbBounds()); return(totalBounds); }
public RectangleDouble GetBounds() { RectangleDouble bounds = RectangleDouble.ZeroIntersection; foreach (VertexData vertexData in Vertices()) { bounds.ExpandToInclude(vertexData.position); } return(bounds); }
public static RectangleDouble GetBounds(this Polygon poly) { RectangleDouble bounds = RectangleDouble.ZeroIntersection; foreach (var point in poly) { bounds.ExpandToInclude(point.X, point.Y); } return(bounds); }
public static RectangleDouble GetBounds(this Polygons polys) { RectangleDouble bounds = RectangleDouble.ZeroIntersection; foreach (var poly in polys) { bounds.ExpandToInclude(poly.GetBounds()); } return(bounds); }
private RectangleDouble GetScreenBounds(AxisAlignedBoundingBox meshBounds) { RectangleDouble screenBounds = RectangleDouble.ZeroIntersection; screenBounds.ExpandToInclude(trackballTumbleWidget.GetScreenPosition(new Vector3(meshBounds.minXYZ.x, meshBounds.minXYZ.y, meshBounds.minXYZ.z))); screenBounds.ExpandToInclude(trackballTumbleWidget.GetScreenPosition(new Vector3(meshBounds.maxXYZ.x, meshBounds.minXYZ.y, meshBounds.minXYZ.z))); screenBounds.ExpandToInclude(trackballTumbleWidget.GetScreenPosition(new Vector3(meshBounds.maxXYZ.x, meshBounds.maxXYZ.y, meshBounds.minXYZ.z))); screenBounds.ExpandToInclude(trackballTumbleWidget.GetScreenPosition(new Vector3(meshBounds.minXYZ.x, meshBounds.maxXYZ.y, meshBounds.minXYZ.z))); screenBounds.ExpandToInclude(trackballTumbleWidget.GetScreenPosition(new Vector3(meshBounds.minXYZ.x, meshBounds.minXYZ.y, meshBounds.maxXYZ.z))); screenBounds.ExpandToInclude(trackballTumbleWidget.GetScreenPosition(new Vector3(meshBounds.maxXYZ.x, meshBounds.minXYZ.y, meshBounds.maxXYZ.z))); screenBounds.ExpandToInclude(trackballTumbleWidget.GetScreenPosition(new Vector3(meshBounds.maxXYZ.x, meshBounds.maxXYZ.y, meshBounds.maxXYZ.z))); screenBounds.ExpandToInclude(trackballTumbleWidget.GetScreenPosition(new Vector3(meshBounds.minXYZ.x, meshBounds.maxXYZ.y, meshBounds.maxXYZ.z))); return(screenBounds); }
public static RectangleDouble GetScreenBounds(AxisAlignedBoundingBox meshBounds, WorldView world) { RectangleDouble screenBounds = RectangleDouble.ZeroIntersection; screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.minXYZ.X, meshBounds.minXYZ.Y, meshBounds.minXYZ.Z))); screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.maxXYZ.X, meshBounds.minXYZ.Y, meshBounds.minXYZ.Z))); screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.maxXYZ.X, meshBounds.maxXYZ.Y, meshBounds.minXYZ.Z))); screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.minXYZ.X, meshBounds.maxXYZ.Y, meshBounds.minXYZ.Z))); screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.minXYZ.X, meshBounds.minXYZ.Y, meshBounds.maxXYZ.Z))); screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.maxXYZ.X, meshBounds.minXYZ.Y, meshBounds.maxXYZ.Z))); screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.maxXYZ.X, meshBounds.maxXYZ.Y, meshBounds.maxXYZ.Z))); screenBounds.ExpandToInclude(world.GetScreenPosition(new Vector3(meshBounds.minXYZ.X, meshBounds.maxXYZ.Y, meshBounds.maxXYZ.Z))); return(screenBounds); }
public static RectangleDouble GetBounds(this IVertexSource source) { RectangleDouble bounds = RectangleDouble.ZeroIntersection; foreach (var vertex in source.Vertices()) { if (!vertex.IsClose && !vertex.IsStop) { bounds.ExpandToInclude(vertex.position); } } return(bounds); }
public ImageBuffer GetImageForCharacter(char character, double xFraction, double yFraction, RGBA_Bytes color) { if (xFraction > 1 || xFraction < 0 || yFraction > 1 || yFraction < 0) { throw new ArgumentException("The x and y fractions must both be between 0 and 1."); } ImageBuffer imageForCharacter; Dictionary <char, ImageBuffer> characterImageCache = StyledTypeFaceImageCache.GetCorrectCache(this.TypeFace, color, this.emSizeInPixels); characterImageCache.TryGetValue(character, out imageForCharacter); if (imageForCharacter != null) { return(imageForCharacter); } IVertexSource glyphForCharacter = GetGlyphForCharacter(character); if (glyphForCharacter == null) { return(null); } glyphForCharacter.rewind(0); double x, y; ShapePath.FlagsAndCommand curCommand = glyphForCharacter.vertex(out x, out y); RectangleDouble bounds = new RectangleDouble(x, y, x, y); while (curCommand != ShapePath.FlagsAndCommand.CommandStop) { bounds.ExpandToInclude(x, y); curCommand = glyphForCharacter.vertex(out x, out y); } int descentExtraHeight = (int)(-DescentInPixels + .5); ImageBuffer charImage = new ImageBuffer(Math.Max((int)(bounds.Width + .5), 1) + 1, Math.Max((int)(EmSizeInPixels + descentExtraHeight + .5), 1) + 1, 32, new BlenderPreMultBGRA()); charImage.OriginOffset = new VectorMath.Vector2(0, descentExtraHeight); Graphics2D graphics = charImage.NewGraphics2D(); graphics.Render(glyphForCharacter, xFraction, yFraction + descentExtraHeight, color); characterImageCache[character] = charImage; return(charImage); }
private void CalculateChildrenBounds() { if (Children.Count > 0) { RectangleDouble boundsOfChildren = new RectangleDouble(double.MaxValue, double.MaxValue, double.MinValue, double.MinValue); foreach (GuiWidget widget in Children) { boundsOfChildren.ExpandToInclude(widget.BoundsRelativeToParent); boundsOfChildren.Left = Math.Min(boundsOfChildren.Left, widget.BoundsRelativeToParent.Left); boundsOfChildren.Bottom = Math.Min(boundsOfChildren.Bottom, widget.BoundsRelativeToParent.Bottom); boundsOfChildren.Right = Math.Max(boundsOfChildren.Right, widget.BoundsRelativeToParent.Right); boundsOfChildren.Top = Math.Max(boundsOfChildren.Top, widget.BoundsRelativeToParent.Top); } LocalBounds = boundsOfChildren; } }
private void CalculateChildrenBounds() { if (Children.Count > 0) { RectangleDouble boundsOfChildren = new RectangleDouble(double.MaxValue, double.MaxValue, double.MinValue, double.MinValue); foreach (GuiWidget widget in Children) { boundsOfChildren.ExpandToInclude(widget.BoundsRelativeToParent); boundsOfChildren.Left = Math.Min(boundsOfChildren.Left, widget.BoundsRelativeToParent.Left); boundsOfChildren.Bottom = Math.Min(boundsOfChildren.Bottom, widget.BoundsRelativeToParent.Bottom); boundsOfChildren.Right = Math.Max(boundsOfChildren.Right, widget.BoundsRelativeToParent.Right); boundsOfChildren.Top = Math.Max(boundsOfChildren.Top, widget.BoundsRelativeToParent.Top); } LocalBounds = boundsOfChildren; } }
public override void FindNamedChildrenRecursive(string nameToSearchFor, List <WidgetAndPosition> foundChildren, RectangleDouble touchingBounds, SearchType seachType, bool allowInvalidItems = true) { foreach (InteractionVolume child in interactionLayer.InteractionVolumes) { string object3DName = child.Name; bool nameFound = false; if (seachType == SearchType.Exact) { if (object3DName == nameToSearchFor) { nameFound = true; } } else { if (nameToSearchFor == "" || object3DName.Contains(nameToSearchFor)) { nameFound = true; } } if (nameFound && child.CollisionVolume != null) { AxisAlignedBoundingBox bounds = child.CollisionVolume.GetAxisAlignedBoundingBox(); bounds = bounds.NewTransformed(child.TotalTransform); RectangleDouble screenBoundsOfObject3D = RectangleDouble.ZeroIntersection; for (int i = 0; i < 4; i++) { screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetTopCorner(i))); screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetBottomCorner(i))); } if (touchingBounds.IsTouching(screenBoundsOfObject3D)) { Vector3 renderPosition = bounds.Center; Vector2 objectCenterScreenSpace = this.World.GetScreenPosition(renderPosition); Point2D screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y); foundChildren.Add(new WidgetAndPosition(this, screenPositionOfObject3D, object3DName, child)); } } } foreach (var child in scene.Children) { string object3DName = child.Name; if (object3DName == null && child.MeshPath != null) { object3DName = Path.GetFileName(child.MeshPath); } bool nameFound = false; if (seachType == SearchType.Exact) { if (object3DName == nameToSearchFor) { nameFound = true; } } else { if (nameToSearchFor == "" || object3DName.Contains(nameToSearchFor)) { nameFound = true; } } if (nameFound) { AxisAlignedBoundingBox bounds = child.TraceData().GetAxisAlignedBoundingBox(); RectangleDouble screenBoundsOfObject3D = RectangleDouble.ZeroIntersection; for (int i = 0; i < 4; i++) { screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetTopCorner(i))); screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetBottomCorner(i))); } if (touchingBounds.IsTouching(screenBoundsOfObject3D)) { Vector3 renderPosition = bounds.Center; Vector2 objectCenterScreenSpace = this.World.GetScreenPosition(renderPosition); Point2D screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y); foundChildren.Add(new WidgetAndPosition(this, screenPositionOfObject3D, object3DName, child)); } } } base.FindNamedChildrenRecursive(nameToSearchFor, foundChildren, touchingBounds, seachType, allowInvalidItems); }
public ImageBuffer GetImageForCharacter(char character, double xFraction, double yFraction, RGBA_Bytes color) { if (xFraction > 1 || xFraction < 0 || yFraction > 1 || yFraction < 0) { throw new ArgumentException("The x and y fractions must both be between 0 and 1."); } ImageBuffer imageForCharacter; Dictionary<char, ImageBuffer> characterImageCache = StyledTypeFaceImageCache.GetCorrectCache(this.TypeFace, color, this.emSizeInPixels); characterImageCache.TryGetValue(character, out imageForCharacter); if (imageForCharacter != null) { return imageForCharacter; } IVertexSource glyphForCharacter = GetGlyphForCharacter(character); if (glyphForCharacter == null) { return null; } glyphForCharacter.rewind(0); double x, y; ShapePath.FlagsAndCommand curCommand = glyphForCharacter.vertex(out x, out y); RectangleDouble bounds = new RectangleDouble(x, y, x, y); while (curCommand != ShapePath.FlagsAndCommand.CommandStop) { bounds.ExpandToInclude(x, y); curCommand = glyphForCharacter.vertex(out x, out y); } int descentExtraHeight = (int)(-DescentInPixels + .5); ImageBuffer charImage = new ImageBuffer(Math.Max((int)(bounds.Width + .5), 1) + 1, Math.Max((int)(EmSizeInPixels + descentExtraHeight + .5), 1) + 1, 32, new BlenderPreMultBGRA()); charImage.OriginOffset = new VectorMath.Vector2(0, descentExtraHeight); Graphics2D graphics = charImage.NewGraphics2D(); graphics.Render(glyphForCharacter, xFraction, yFraction + descentExtraHeight, color); characterImageCache[character] = charImage; return charImage; }
private void DoLayoutChildren(LayoutEventArgs layoutEventArgs) { GuiWidget parent = layoutEventArgs.ParentWidget; if (parent.CountVisibleChildren() == 0) { return; } RectangleDouble boundsOfAllChildrenIncludingMargin = RectangleDouble.ZeroIntersection; double totalWidthWithMargin = 0; double totalHeightWithMargin = 0; double totalWidthOfStaticItems = 0; double totalHeightOfStaticItems = 0; int numItemsNeedingExpanding = 0; double totalMinimumWidthOfAllItems = 0; double totalMinimumHeightOfAllItems = 0; for (int childIndex = 0; childIndex < parent.Children.Count; childIndex++) { GuiWidget child = parent.Children[childIndex]; if (child.Visible == false) { continue; } RectangleDouble childBoundsWithMargin = child.LocalBounds; childBoundsWithMargin.Inflate(child.Margin); totalWidthWithMargin += childBoundsWithMargin.Width; totalHeightWithMargin += childBoundsWithMargin.Height; boundsOfAllChildrenIncludingMargin.ExpandToInclude(childBoundsWithMargin); switch (FlowDirection) { case UI.FlowDirection.LeftToRight: case UI.FlowDirection.RightToLeft: totalMinimumWidthOfAllItems += child.MinimumSize.x + child.Margin.Width; totalMinimumHeightOfAllItems = Math.Max(totalMinimumHeightOfAllItems, child.MinimumSize.y + child.Margin.Height); if (child.HAnchorIsSet(HAnchor.ParentLeftRight)) { numItemsNeedingExpanding++; totalWidthOfStaticItems += child.Margin.Width; } else if (child.HAnchor == HAnchor.AbsolutePosition || child.HAnchorIsSet(HAnchor.FitToChildren)) { totalWidthOfStaticItems += childBoundsWithMargin.Width; } else { throw new Exception("Only None or ParentLeftRight are valid HAnchor for a horizontal flowWidget."); } break; case UI.FlowDirection.TopToBottom: case UI.FlowDirection.BottomToTop: totalMinimumWidthOfAllItems = Math.Max(totalMinimumWidthOfAllItems, child.MinimumSize.x + child.Margin.Width); totalMinimumHeightOfAllItems += child.MinimumSize.y + child.Margin.Height; if (child.VAnchorIsSet(VAnchor.ParentBottomTop)) { numItemsNeedingExpanding++; totalHeightOfStaticItems += child.Margin.Height; } else if (child.VAnchor == VAnchor.AbsolutePosition || child.VAnchorIsSet(VAnchor.FitToChildren)) { totalHeightOfStaticItems += childBoundsWithMargin.Height; } else { throw new Exception("Only None or ParentBottomTop are valid VAnchor for a vertial flowWidget."); } break; default: throw new NotImplementedException(); } } switch (FlowDirection) { case UI.FlowDirection.LeftToRight: { double curX = parent.Padding.Left; foreach (GuiWidget child in parent.Children) { if (child.Visible == true) { double newX = curX - child.LocalBounds.Left + child.Margin.Left; child.OriginRelativeParent = new Vector2(newX, child.OriginRelativeParent.y); if (child.HAnchorIsSet(HAnchor.ParentLeftRight)) { RectangleDouble curChildBounds = child.LocalBounds; double newWidth = (parent.LocalBounds.Width - parent.Padding.Width - totalWidthOfStaticItems) / numItemsNeedingExpanding; child.LocalBounds = new RectangleDouble(curChildBounds.Left, curChildBounds.Bottom, newWidth, curChildBounds.Top); } curX += child.LocalBounds.Width + child.Margin.Width; } } } break; case UI.FlowDirection.RightToLeft: { double curX = parent.LocalBounds.Right - parent.Padding.Right; foreach (GuiWidget child in parent.Children) { if (child.Visible == true) { if (child.HAnchorIsSet(HAnchor.ParentLeftRight)) { RectangleDouble curChildBounds = child.LocalBounds; double newWidth = (parent.LocalBounds.Width - parent.Padding.Width - totalWidthOfStaticItems) / numItemsNeedingExpanding; child.LocalBounds = new RectangleDouble(curChildBounds.Left, curChildBounds.Bottom, newWidth, curChildBounds.Top); } double newX = curX - child.LocalBounds.Left - (child.LocalBounds.Width + child.Margin.Right); child.OriginRelativeParent = new Vector2(newX, child.OriginRelativeParent.y); curX -= (child.LocalBounds.Width + child.Margin.Width); } } } break; case UI.FlowDirection.BottomToTop: { double curY = parent.Padding.Bottom; foreach (GuiWidget child in parent.Children) { if (child.Visible == true) { double newY = curY - child.LocalBounds.Bottom + child.Margin.Bottom; child.OriginRelativeParent = new Vector2(child.OriginRelativeParent.x, newY); if (child.VAnchorIsSet(VAnchor.ParentBottomTop)) { RectangleDouble curChildBounds = child.LocalBounds; double newHeight = (parent.LocalBounds.Height - parent.Padding.Height - totalHeightOfStaticItems) / numItemsNeedingExpanding; child.LocalBounds = new RectangleDouble(curChildBounds.Left, curChildBounds.Bottom, curChildBounds.Right, newHeight); } curY += child.LocalBounds.Height + child.Margin.Height; } } } break; case UI.FlowDirection.TopToBottom: { double curY = parent.LocalBounds.Top - parent.Padding.Top; foreach (GuiWidget child in parent.Children) { if (child.Visible == true) { if (child.VAnchorIsSet(VAnchor.ParentBottomTop)) { RectangleDouble curChildBounds = child.LocalBounds; double newHeight = (parent.LocalBounds.Height - parent.Padding.Height - totalHeightOfStaticItems) / numItemsNeedingExpanding; child.LocalBounds = new RectangleDouble(curChildBounds.Left, curChildBounds.Bottom, curChildBounds.Right, newHeight); } double newY = curY - child.LocalBounds.Bottom - (child.LocalBounds.Height + child.Margin.Top); child.OriginRelativeParent = new Vector2(child.OriginRelativeParent.x, newY); curY -= (child.LocalBounds.Height + child.Margin.Height); } } } break; default: throw new NotImplementedException(); } }
private void DoLayoutChildren(LayoutEventArgs layoutEventArgs) { GuiWidget parent = layoutEventArgs.ParentWidget; if (parent.CountVisibleChildren() == 0) { return; } RectangleDouble boundsOfAllChildrenIncludingMargin = RectangleDouble.ZeroIntersection; var totalSizeWithMargin = Vector2.Zero; var totalSizeOfStaticItems = Vector2.Zero; var totalMinimumSizeOfAllItems = Vector2.Zero; double totalWidthWithMargin = 0; double totalHeightWithMargin = 0; foreach (GuiWidget child in parent.Children) { if (parent.HasBeenClosed) { return; } if (child.Visible == false) { continue; } RectangleDouble childBoundsWithMargin = child.LocalBounds; childBoundsWithMargin.Inflate(child.DeviceMarginAndBorder); totalWidthWithMargin += childBoundsWithMargin.Width; totalHeightWithMargin += childBoundsWithMargin.Height; boundsOfAllChildrenIncludingMargin.ExpandToInclude(childBoundsWithMargin); } int numItemsNeedingExpanding = CalculateContentSizes(parent, ref totalSizeWithMargin, ref totalSizeOfStaticItems, ref totalMinimumSizeOfAllItems); var availableSpaceInParent = new Vector2(parent.LocalBounds.Width - parent.DevicePadding.Width, parent.LocalBounds.Height - parent.DevicePadding.Height); var sizePerChild = new Vector2((availableSpaceInParent.X - totalSizeOfStaticItems.X) / numItemsNeedingExpanding, (availableSpaceInParent.Y - totalSizeOfStaticItems.Y) / numItemsNeedingExpanding); if (numItemsNeedingExpanding > 0) { // Iterate all the children and add back in and size that they can't grow bigger than back into the sizePerChild. var extraSizeDueToMax = default(Vector2); var maxSizeCount = default(Point2D); foreach (GuiWidget child in parent.Children) { if (child.MaximumSize.X < sizePerChild.X) { extraSizeDueToMax.X += sizePerChild.X - child.MaximumSize.X; maxSizeCount.x++; } if (child.MaximumSize.Y < sizePerChild.Y) { extraSizeDueToMax.Y += sizePerChild.Y - child.MaximumSize.Y; maxSizeCount.y++; } } // add back in the amount this item cannot grow to the amount we will try to give each child if (maxSizeCount.x > 0) { sizePerChild.X += extraSizeDueToMax.X / (numItemsNeedingExpanding - maxSizeCount.x); } if (maxSizeCount.y > 0) { sizePerChild.Y += extraSizeDueToMax.Y / (numItemsNeedingExpanding - maxSizeCount.y); } } switch (FlowDirection) { case UI.FlowDirection.LeftToRight: { double curX = parent.DevicePadding.Left; foreach (GuiWidget child in parent.Children) { if (parent.HasBeenClosed) { return; } if (child.Visible == true) { double newX = curX - child.LocalBounds.Left + child.DeviceMarginAndBorder.Left; child.OriginRelativeParent = new Vector2(newX, child.OriginRelativeParent.Y); if (child.HAnchorIsSet(HAnchor.Stretch)) { RectangleDouble curChildBounds = child.LocalBounds; child.LocalBounds = new RectangleDouble(curChildBounds.Left, curChildBounds.Bottom, curChildBounds.Left + sizePerChild.X, curChildBounds.Top); } curX += child.LocalBounds.Width + child.DeviceMarginAndBorder.Width; } } } break; case UI.FlowDirection.RightToLeft: { double curX = parent.LocalBounds.Right - parent.DevicePadding.Right; foreach (GuiWidget child in parent.Children) { if (parent.HasBeenClosed) { return; } if (child.Visible == true) { if (child.HAnchorIsSet(HAnchor.Stretch)) { RectangleDouble curChildBounds = child.LocalBounds; child.LocalBounds = new RectangleDouble(curChildBounds.Left, curChildBounds.Bottom, curChildBounds.Left + sizePerChild.X, curChildBounds.Top); } double newX = curX - child.LocalBounds.Left - (child.LocalBounds.Width + child.DeviceMarginAndBorder.Right); child.OriginRelativeParent = new Vector2(newX, child.OriginRelativeParent.Y); curX -= child.LocalBounds.Width + child.DeviceMarginAndBorder.Width; } } } break; case UI.FlowDirection.BottomToTop: { double curY = parent.DevicePadding.Bottom; foreach (GuiWidget child in parent.Children) { if (parent.HasBeenClosed) { return; } if (child.Visible == true) { double newY = curY - child.LocalBounds.Bottom + child.DeviceMarginAndBorder.Bottom; child.OriginRelativeParent = new Vector2(child.OriginRelativeParent.X, newY); if (child.VAnchorIsSet(VAnchor.Stretch)) { RectangleDouble curChildBounds = child.LocalBounds; child.LocalBounds = new RectangleDouble(curChildBounds.Left, curChildBounds.Bottom, curChildBounds.Right, curChildBounds.Bottom + sizePerChild.Y); } curY += child.LocalBounds.Height + child.DeviceMarginAndBorder.Height; } } } break; case UI.FlowDirection.TopToBottom: { double curY = parent.LocalBounds.Top - parent.DevicePadding.Top; foreach (GuiWidget child in parent.Children) { if (parent.HasBeenClosed) { return; } if (child.Visible == true) { if (child.VAnchorIsSet(VAnchor.Stretch)) { RectangleDouble curChildBounds = child.LocalBounds; child.LocalBounds = new RectangleDouble(curChildBounds.Left, curChildBounds.Bottom, curChildBounds.Right, curChildBounds.Bottom + sizePerChild.Y); } double newY = curY - child.LocalBounds.Bottom - (child.LocalBounds.Height + child.DeviceMarginAndBorder.Top); child.OriginRelativeParent = new Vector2(child.OriginRelativeParent.X, newY); curY -= child.LocalBounds.Height + child.DeviceMarginAndBorder.Height; } } } break; default: throw new NotImplementedException(); } }
public RectangleDouble GetChildrenBoundsIncludingMargins(bool considerChildAnchor = false) { RectangleDouble boundsOfAllChildrenIncludingMargin = new RectangleDouble(); if (this.CountVisibleChildren() > 0) { Vector2 minSize = Vector2.Zero; boundsOfAllChildrenIncludingMargin = RectangleDouble.ZeroIntersection; bool foundHBounds = false; bool foundVBounds = false; foreach (GuiWidget child in Children) { if (child.Visible == false) { continue; } if (considerChildAnchor) { minSize.x = Math.Max(child.Width + child.Margin.Width, minSize.x); minSize.y = Math.Max(child.Height + child.Margin.Height, minSize.y); RectangleDouble childBoundsWithMargin = child.BoundsRelativeToParent; childBoundsWithMargin.Inflate(child.Margin); if (!child.HAnchorIsFloating) { foundHBounds = true; // it can't move so make sure our horizontal bounds enclose it if (boundsOfAllChildrenIncludingMargin.Right < childBoundsWithMargin.Right) { boundsOfAllChildrenIncludingMargin.Right = childBoundsWithMargin.Right; } if (boundsOfAllChildrenIncludingMargin.Left > childBoundsWithMargin.Left) { boundsOfAllChildrenIncludingMargin.Left = childBoundsWithMargin.Left; } } if (!child.VAnchorIsFloating) { foundVBounds = true; // it can't move so make sure our vertical bounds enclose it if (boundsOfAllChildrenIncludingMargin.Top < childBoundsWithMargin.Top) { boundsOfAllChildrenIncludingMargin.Top = childBoundsWithMargin.Top; } if (boundsOfAllChildrenIncludingMargin.Bottom > childBoundsWithMargin.Bottom) { boundsOfAllChildrenIncludingMargin.Bottom = childBoundsWithMargin.Bottom; } } } else { RectangleDouble childBoundsWithMargin = child.BoundsRelativeToParent; childBoundsWithMargin.Inflate(child.Margin); boundsOfAllChildrenIncludingMargin.ExpandToInclude(childBoundsWithMargin); } } if (considerChildAnchor) { if (foundHBounds) { boundsOfAllChildrenIncludingMargin.Right = boundsOfAllChildrenIncludingMargin.Left + Math.Max(boundsOfAllChildrenIncludingMargin.Width, minSize.x); } else { boundsOfAllChildrenIncludingMargin.Left = 0; boundsOfAllChildrenIncludingMargin.Right = minSize.x; } if (foundVBounds) { boundsOfAllChildrenIncludingMargin.Top = boundsOfAllChildrenIncludingMargin.Bottom + Math.Max(boundsOfAllChildrenIncludingMargin.Height, minSize.y); } else { boundsOfAllChildrenIncludingMargin.Bottom = 0; boundsOfAllChildrenIncludingMargin.Top = minSize.y; } } } return boundsOfAllChildrenIncludingMargin; }
private int CalculateContentSizes(GuiWidget parent, ref Vector2 totalSizeWithMargin, ref Vector2 totalSizeOfStaticItems, ref Vector2 totalMinimumSizeOfAllItems) { int numItemsNeedingExpanding = 0; RectangleDouble boundsOfAllChildrenIncludingMargin = RectangleDouble.ZeroIntersection; foreach (GuiWidget child in parent.Children) { if (child.Visible == false) { continue; } RectangleDouble childBoundsWithMargin = child.LocalBounds; childBoundsWithMargin.Inflate(child.DeviceMarginAndBorder); totalSizeWithMargin.X += childBoundsWithMargin.Width; totalSizeWithMargin.Y += childBoundsWithMargin.Height; boundsOfAllChildrenIncludingMargin.ExpandToInclude(childBoundsWithMargin); switch (FlowDirection) { case UI.FlowDirection.LeftToRight: case UI.FlowDirection.RightToLeft: totalMinimumSizeOfAllItems.X += child.MinimumFlowSize().X + child.DeviceMarginAndBorder.Width; totalMinimumSizeOfAllItems.Y = Math.Max(totalMinimumSizeOfAllItems.Y, child.MinimumFlowSize().Y + child.DeviceMarginAndBorder.Height); if (child.HAnchorIsSet(HAnchor.Stretch)) { numItemsNeedingExpanding++; totalSizeOfStaticItems.X += child.DeviceMarginAndBorder.Width; } else if (child.HAnchor == HAnchor.Absolute || child.HAnchorIsSet(HAnchor.Fit) || child.HAnchorIsSet(HAnchor.MinFitOrStretch)) { totalSizeOfStaticItems.X += childBoundsWithMargin.Width; } else { throw new Exception("Only Absolute or Stretch are valid HAnchor for a horizontal flowWidget."); } break; case UI.FlowDirection.TopToBottom: case UI.FlowDirection.BottomToTop: totalMinimumSizeOfAllItems.X = Math.Max(totalMinimumSizeOfAllItems.X, child.MinimumFlowSize().X + child.DeviceMarginAndBorder.Width); totalMinimumSizeOfAllItems.Y += child.MinimumFlowSize().Y + child.DeviceMarginAndBorder.Height; if (child.VAnchorIsSet(VAnchor.Stretch)) { numItemsNeedingExpanding++; totalSizeOfStaticItems.Y += child.DeviceMarginAndBorder.Height; } else if (child.VAnchor == VAnchor.Absolute || child.VAnchorIsSet(VAnchor.Fit)) { totalSizeOfStaticItems.Y += childBoundsWithMargin.Height; } else { throw new Exception("Only Absolute or Stretch are valid VAnchor for a vertical flowWidget."); } break; default: throw new NotImplementedException(); } } return(numItemsNeedingExpanding); }
public override string ReadLine() { // Send any commands that are queue before moving on to the internal stream. string nextCommand = queuedCommands.ReadLine(); if (nextCommand != null) { return(nextCommand); } switch (RecoveryState) { // heat the extrude to remove it from the part case RecoveryState.RemoveHeating: // TODO: make sure we heat up all the extruders that we need to (all that are used) queuedCommands.Add("G21; set units to millimeters"); queuedCommands.Add("M107; fan off"); queuedCommands.Add("T0; set the active extruder to 0"); queuedCommands.Add("G90; use absolute coordinates"); queuedCommands.Add("G92 E0; reset the expected extruder position"); queuedCommands.Add("M82; use absolute distance for extrusion"); bool hasHeatedBed = printer.Settings.GetValue <bool>(SettingsKey.has_heated_bed); double bedTemp = printer.Settings.GetValue <double>(SettingsKey.bed_temperature); if (hasHeatedBed && bedTemp > 0) { // start heating the bed queuedCommands.Add($"M140 S{bedTemp}"); } // heat up the extruder queuedCommands.Add("M109 S{0}".FormatWith(printer.Settings.Helpers.ExtruderTemperature(0))); if (hasHeatedBed && bedTemp > 0) { // finish heating the bed queuedCommands.Add($"M190 S{bedTemp}"); } RecoveryState = RecoveryState.Raising; return(""); // remove it from the part case RecoveryState.Raising: // We don't know where the printer is for sure (it make have been turned off). Disable leveling until we know where it is. PrintLevelingStream.AllowLeveling = false; queuedCommands.Add("M114 ; get current position"); queuedCommands.Add("G91 ; move relative"); queuedCommands.Add("G1 Z10 F{0}".FormatWith(printer.Settings.ZSpeed())); queuedCommands.Add("G90 ; move absolute"); RecoveryState = RecoveryState.Homing; return(""); // if top homing, home the extruder case RecoveryState.Homing: if (printer.Settings.GetValue <bool>(SettingsKey.z_homes_to_max)) { queuedCommands.Add("G28"); } else { // home x queuedCommands.Add("G28 X0"); // home y queuedCommands.Add("G28 Y0"); // move to the place we can home z from Vector2 recoveryPositionXy = printer.Settings.GetValue <Vector2>(SettingsKey.recover_position_before_z_home); queuedCommands.Add("G1 X{0:0.###}Y{1:0.###}F{2}".FormatWith(recoveryPositionXy.X, recoveryPositionXy.Y, printer.Settings.XSpeed())); // home z queuedCommands.Add("G28 Z0"); } // We now know where the printer is re-enable print leveling PrintLevelingStream.AllowLeveling = true; RecoveryState = RecoveryState.FindingRecoveryLayer; return(""); // This is to recover printing if an out a filament occurs. // Help the user move the extruder down to just touching the part case RecoveryState.FindingRecoveryLayer: if (false) // help the user get the head to the right position { // move to above the completed print // move over a know good part of the model at the current top layer (extrude vertex from gcode) // let the user move down until they like the height // calculate that position and continue } else // we are resuming because of disconnect or reset, skip this { RecoveryState = RecoveryState.SkippingGCode; goto case RecoveryState.SkippingGCode; } case RecoveryState.SkippingGCode: // run through the gcode that the device expected looking for things like temp // and skip everything else until we get to the point we left off last time int commandCount = 0; boundsOfSkippedLayers = RectangleDouble.ZeroIntersection; while (internalStream.GCodeFile.PercentComplete(internalStream.LineIndex) < percentDone) { string line = internalStream.ReadLine(); if (line == null) { break; } commandCount++; // make sure we don't parse comments if (line.Contains(";")) { line = line.Split(';')[0]; } lastDestination = GetPosition(line, lastDestination); if (commandCount > 100) { boundsOfSkippedLayers.ExpandToInclude(lastDestination.position.Xy); } // check if the line is something we want to send to the printer (like a temp) if (line.StartsWith("M109") || // heat and wait extruder line.StartsWith("M104") || // heat extruder line.StartsWith("M190") || // heat and wait bed line.StartsWith("M140") || // heat bed line.StartsWith("T") || // switch extruder line.StartsWith("M106") || // fan on line.StartsWith("M107") || // fan off line.StartsWith("G92")) // set position { return(line); } } RecoveryState = RecoveryState.PrimingAndMovingToStart; // make sure we always- pick up the last movement boundsOfSkippedLayers.ExpandToInclude(lastDestination.position.Xy); return(""); case RecoveryState.PrimingAndMovingToStart: { if (printer.Settings.GetValue("z_homes_to_max") == "0") // we are homed to the bed { // move to the height we can recover printing from Vector2 recoverPositionXy = printer.Settings.GetValue <Vector2>(SettingsKey.recover_position_before_z_home); queuedCommands.Add(CreateMovementLine(new PrinterMove(new VectorMath.Vector3(recoverPositionXy.X, recoverPositionXy.Y, lastDestination.position.Z), 0, printer.Settings.ZSpeed()))); } double extruderWidth = printer.Settings.GetValue <double>(SettingsKey.nozzle_diameter); // move to a position outside the printed bounds queuedCommands.Add(CreateMovementLine(new PrinterMove( new Vector3(boundsOfSkippedLayers.Left - extruderWidth * 2, boundsOfSkippedLayers.Bottom + boundsOfSkippedLayers.Height / 2, lastDestination.position.Z), 0, printer.Settings.XSpeed()))); // let's prime the extruder queuedCommands.Add("G1 E10 F{0}".FormatWith(printer.Settings.EFeedRate(0))); // extrude 10 queuedCommands.Add("G1 E9"); // and retract a bit // move to the actual print position queuedCommands.Add(CreateMovementLine(new PrinterMove(lastDestination.position, 0, printer.Settings.XSpeed()))); /// reset the printer to know where the filament should be queuedCommands.Add("G92 E{0}".FormatWith(lastDestination.extrusion)); RecoveryState = RecoveryState.PrintingSlow; } return(""); case RecoveryState.PrintingSlow: { string lineToSend = internalStream.ReadLine(); if (lineToSend == null) { return(null); } if (!GCodeFile.IsLayerChange(lineToSend)) { // have not seen the end of this layer so keep printing slow if (LineIsMovement(lineToSend)) { PrinterMove currentMove = GetPosition(lineToSend, lastDestination); PrinterMove moveToSend = currentMove; moveToSend.feedRate = recoverFeedRate; lineToSend = CreateMovementLine(moveToSend, lastDestination); lastDestination = currentMove; return(lineToSend); } return(lineToSend); } } // we only fall through to here after seeing the next "; Layer:" RecoveryState = RecoveryState.PrintingToEnd; return(""); case RecoveryState.PrintingToEnd: return(internalStream.ReadLine()); } return(null); }
private void DoLayoutChildren(LayoutEventArgs layoutEventArgs) { GuiWidget parent = layoutEventArgs.ParentWidget; if (parent.CountVisibleChildren() == 0) { return; } RectangleDouble boundsOfAllChildrenIncludingMargin = RectangleDouble.ZeroIntersection; var totalSizeWithMargin = Vector2.Zero; var totalSizeOfStaticItems = Vector2.Zero; var totalMinimumSizeOfAllItems = Vector2.Zero; double totalWidthWithMargin = 0; double totalHeightWithMargin = 0; foreach (GuiWidget child in parent.Children) { if (parent.HasBeenClosed) { return; } if (child.Visible == false) { continue; } RectangleDouble childBoundsWithMargin = child.LocalBounds; childBoundsWithMargin.Inflate(child.DeviceMarginAndBorder); totalWidthWithMargin += childBoundsWithMargin.Width; totalHeightWithMargin += childBoundsWithMargin.Height; boundsOfAllChildrenIncludingMargin.ExpandToInclude(childBoundsWithMargin); } int numItemsNeedingExpanding = CalculateContentSizes(parent, ref totalSizeWithMargin, ref totalSizeOfStaticItems, ref totalMinimumSizeOfAllItems); switch (FlowDirection) { case UI.FlowDirection.LeftToRight: { double curX = parent.DevicePadding.Left; foreach (GuiWidget child in parent.Children) { if (parent.HasBeenClosed) { return; } if (child.Visible == true) { double newX = curX - child.LocalBounds.Left + child.DeviceMarginAndBorder.Left; child.OriginRelativeParent = new Vector2(newX, child.OriginRelativeParent.Y); if (child.HAnchorIsSet(HAnchor.Stretch)) { RectangleDouble curChildBounds = child.LocalBounds; double newWidth = (parent.LocalBounds.Width - parent.DevicePadding.Width - totalSizeOfStaticItems.X) / numItemsNeedingExpanding; child.LocalBounds = new RectangleDouble(curChildBounds.Left, curChildBounds.Bottom, curChildBounds.Left + newWidth, curChildBounds.Top); } curX += child.LocalBounds.Width + child.DeviceMarginAndBorder.Width; } } } break; case UI.FlowDirection.RightToLeft: { double curX = parent.LocalBounds.Right - parent.DevicePadding.Right; foreach (GuiWidget child in parent.Children) { if (parent.HasBeenClosed) { return; } if (child.Visible == true) { if (child.HAnchorIsSet(HAnchor.Stretch)) { RectangleDouble curChildBounds = child.LocalBounds; double newWidth = (parent.LocalBounds.Width - parent.DevicePadding.Width - totalSizeOfStaticItems.X) / numItemsNeedingExpanding; child.LocalBounds = new RectangleDouble(curChildBounds.Left, curChildBounds.Bottom, curChildBounds.Left + newWidth, curChildBounds.Top); } double newX = curX - child.LocalBounds.Left - (child.LocalBounds.Width + child.DeviceMarginAndBorder.Right); child.OriginRelativeParent = new Vector2(newX, child.OriginRelativeParent.Y); curX -= child.LocalBounds.Width + child.DeviceMarginAndBorder.Width; } } } break; case UI.FlowDirection.BottomToTop: { double curY = parent.DevicePadding.Bottom; foreach (GuiWidget child in parent.Children) { if (parent.HasBeenClosed) { return; } if (child.Visible == true) { double newY = curY - child.LocalBounds.Bottom + child.DeviceMarginAndBorder.Bottom; child.OriginRelativeParent = new Vector2(child.OriginRelativeParent.X, newY); if (child.VAnchorIsSet(VAnchor.Stretch)) { RectangleDouble curChildBounds = child.LocalBounds; double newHeight = (parent.LocalBounds.Height - parent.DevicePadding.Height - totalSizeOfStaticItems.Y) / numItemsNeedingExpanding; child.LocalBounds = new RectangleDouble(curChildBounds.Left, curChildBounds.Bottom, curChildBounds.Right, curChildBounds.Bottom + newHeight); } curY += child.LocalBounds.Height + child.DeviceMarginAndBorder.Height; } } } break; case UI.FlowDirection.TopToBottom: { double curY = parent.LocalBounds.Top - parent.DevicePadding.Top; foreach (GuiWidget child in parent.Children) { if (parent.HasBeenClosed) { return; } if (child.Visible == true) { if (child.VAnchorIsSet(VAnchor.Stretch)) { RectangleDouble curChildBounds = child.LocalBounds; double newHeight = (parent.LocalBounds.Height - parent.DevicePadding.Height - totalSizeOfStaticItems.Y) / numItemsNeedingExpanding; // - child.DeviceMarginAndBorder.Height; child.LocalBounds = new RectangleDouble(curChildBounds.Left, curChildBounds.Bottom, curChildBounds.Right, curChildBounds.Bottom + newHeight); } double newY = curY - child.LocalBounds.Bottom - (child.LocalBounds.Height + child.DeviceMarginAndBorder.Top); child.OriginRelativeParent = new Vector2(child.OriginRelativeParent.X, newY); curY -= child.LocalBounds.Height + child.DeviceMarginAndBorder.Height; } } } break; default: throw new NotImplementedException(); } }