// FIXME: Only render dirty rects public void Render(BoundingRect rect) { var ctx = Surface.GetDrawingContext (); ApplyTransform (ctx); // If we were alredy rendering, stop it if (renderFiber != null && renderFiber.Status == FutureStatus.Pending) renderFiber.Cancel (); renderFiber = Render (rect, ctx); // Render children last //foreach (var child in Children) { // child.Render (rect.GetIntersection (child.Bounds)); //} }
/// <summary> /// Contains the rendering logic for this Layer2d. /// </summary> /// <remarks> /// The rendering logic in a Layer2d can be defined either by setting the <see cref="P:Renderer"/> property, /// or by overriding this method in a subclass. /// In either case, the rendering routine may be a fiber that continues rendering, possibly in an infinite loop (i.e for animation), /// or it can be a one-off draw something and return routine. If the first case is desired, it is recommended that /// it be implemented as an asynchronous method that is processed by the postcompiler. At the least, a Future that supports cancellation /// must be returned if the method does not complete synchronously. /// For an explanation, take an animation that continues in an indefinite loop, delaying for a certain period between iterations. /// If another layer is placed atop the animation layer, and then moved, exposing a previously unexposed region of the animation layer, /// that region needs to be drawn expeditiously. To accomplish that, the view system will cancel the animation's Future (as returned by /// a previous invocation of this method), and immediately invoke this method again. Thus, any state needed to correctly render the layer /// must not be stored in locals of an asynchronous method. /// </remarks> /// <param name='rect'> /// The BoundingRect into which rendering is required. /// </param> /// <param name='ctx'> /// The ISurface2d into which rendering is required. /// </param> protected virtual Future Render(BoundingRect rect, IContext2d ctx) { if (Renderer != null) return Renderer (this, rect, ctx); return Future.Fulfilled; }
/** * Splits the rect argument into the area that overlaps this rect (this is * the return value) and an array of areas that do not overlap (this is the * remainderRects argument, which must be passed as an empty array). * @param rect The rectangle to intersect with this. * @param remainderRects An empty array that will be populated with the areas * of the rect parameter that do not intersect with this rect. * @return The intersection of this rectangle and the rect argument. */ public BoundingRect SplitIntersection(BoundingRect rect, out List<BoundingRect> remainder) { remainder = new List<BoundingRect> (); if (!this.Intersects (rect)) { remainder.Add (rect); return null; } // Copy the properties of rect into intersection; we trim this to size later var intersection = rect; // Check for a non-overlapped rect on the left if (intersection.X < this.X) { var left = new BoundingRect { X = intersection.X, Y = intersection.Y, Width = this.X - intersection.X, Height = intersection.Height }; // Insert the rect remainder.Add (left); // Adjust the dimensions of the intersection intersection.X = this.X; intersection.Width -= left.Width; } // Check for a non-overlapped rect on the right if (intersection.X + intersection.Width > this.X + this.Width) { var right = new BoundingRect { X = this.X + this.Width, Y = intersection.Y, Width = intersection.Width - (this.X + this.Width - intersection.X), Height = intersection.Height }; // Insert the rect remainder.Add (right); // Adjust dimensions of the intersection intersection.Width -= right.Width; } // Check for a non-overlapped rect above if (intersection.Y < this.Y) { var top = new BoundingRect { X = intersection.X, Y = intersection.Y, Width = intersection.Width, Height = this.Y - intersection.Y }; // Insert the rect remainder.Add (top); // Adjust the dimensions of the intersection intersection.Y = this.Y; intersection.Height -= top.Height; } // Check for a non-overlapped rect below if (intersection.Y + intersection.Height > this.Y + this.Height) { var bottom = new BoundingRect { X = intersection.X, Y = this.Y + this.Height, Width = intersection.Width, Height = intersection.Height - (this.Y + this.Height - intersection.Y) }; // Insert the rect remainder.Add (bottom); // Adjust dimensions of the intersection intersection.Height -= bottom.Height; } return intersection; }
void ChangeBounds(BoundingRect old, double unused) { Change.Fire (new BoundsChange (old, this)); }
public bool SamePosition(BoundingRect rect) { return this.X == rect.X && this.Y == rect.Y; }
public bool SameSize(BoundingRect rect) { return this.Width == rect.Width && this.Height == rect.Height; }
/** * Gets the intersect of this rectangle with the supplied argument. * @param rect The rectangle to intersect with this. * @return A rectangle that represents the intersection of the two rectangles. */ public BoundingRect GetIntersection(BoundingRect rect) { return new BoundingRect { X = this.X > rect.X ? this.X : rect.X, Y = this.Y > rect.Y ? this.Y : rect.Y, X2 = this.X2 < rect.X2 ? this.X2 : rect.X2, Y2 = this.Y2 < rect.Y2 ? this.Y2 : rect.Y2 }; }
/** * Check if this rectangle intersects the argument. * @param rect The rect to check for an intersection. * @return True if the rects intersect. */ public bool Intersects(BoundingRect rect) { return ((this.X + this.Width > rect.X) && (this.Y + this.Height > rect.Y) && (this.X < rect.X + rect.Width) && (this.Y < rect.Y + rect.Height)); }
/** * Gets the smallest rectangle capable of containing this rect and the supplied * argument. * @param rect The rectangle to add to this. * @return The smallest rectangle that can contain this rect and the argument. */ public BoundingRect GetAddition(BoundingRect rect) { return new BoundingRect { X = this.X < rect.X ? this.X : rect.X, Y = this.Y < rect.Y ? this.Y : rect.Y, X2 = this.X2 > rect.X2 ? this.X2 : rect.X2, Y2 = this.Y2 > rect.Y2 ? this.Y2 : rect.Y2 }; }
/** * Increases the size of the rect to encompass the supplied argument. * @param rect The rect to encompass. */ public void ExpandToInclude(BoundingRect rect) { var addition = GetAddition (rect); this.X = addition.X; this.Y = addition.Y; this.Width = addition.Width; this.Height = addition.Height; }
public bool Equals(BoundingRect rect) { return this.X == rect.X && this.Y == rect.Y && this.Width == rect.Width && this.Height == rect.Height; }
/** * Clips this rectangle to the intersection with the supplied argument. * @param rect The rectangle to clip to. */ public void ClipToIntersection(BoundingRect rect) { var intersect = GetIntersection (rect); this.X = intersect.X; this.Y = intersect.Y; this.Width = intersect.Width; this.Height = intersect.Height; }
public BoundsChange(BoundingRect old, BoundingRect current) { OldBounds = old; Bounds = current; }