Esempio n. 1
0
        /// <summary>
        /// Invalidates the specified region of the canvas (adds it to the canvas's update region,
        /// which is the area that will be repainted at the next paint operation), and causes a paint
        /// message to be sent to the canvas.
        /// </summary>
        /// <param name="bounds">A rectangle object that represents the region to invalidate.</param>
        public virtual void InvalidateBounds(RectangleFx bounds)
        {
            PDebug.ProcessInvalidate();

            if (regionManagement)
            {
                // Hack: Invalidate the bounds of the previously invalidated rectangle
                // and the current rectangle, since invalidating lots of small rectangles
                // causes a performance hit.
                if (invalidatedBounds.IsEmpty)
                {
                    invalidatedBounds = bounds;
                }
                else
                {
                    invalidatedBounds = RectangleFxtensions.Union(invalidatedBounds, bounds);
                }

                RectangleFx insetRect = new RectangleFx(invalidatedBounds.X - 1, invalidatedBounds.Y - 1,
                                                        invalidatedBounds.Width + 2, invalidatedBounds.Height + 2);

                int x      = (int)Math.Floor(insetRect.X);
                int y      = (int)Math.Floor(insetRect.Y);
                int width  = (int)Math.Ceiling(insetRect.Right - x);
                int height = (int)Math.Ceiling(insetRect.Bottom - y);
                Invalidate(new System.Drawing.Rectangle(x, y, width, height));
            }
            else
            {
                Invalidate();
            }
        }
        public override PointFx GetViewPosition(RectangleFx bounds)
        {
            PointFx pos = PointFx.Empty;

            if (camera != null)
            {
                // First we compute the union of all the layers
                RectangleFx layerBounds = camera.UnionOfLayerFullBounds;

                // Then we put the bounds into camera coordinates and
                // union the camera bounds
                layerBounds = camera.ViewToLocal(layerBounds);
                layerBounds = RectangleFxtensions.Union(layerBounds, bounds);

                // Rather than finding the distance from the upper left corner
                // of the window to the upper left corner of the document -
                // we instead find the distance from the lower right corner
                // of the window to the upper left corner of the document
                // THEN we measure the offset from the lower right corner
                // of the document
                int x = (int)(layerBounds.Width - (bounds.X + bounds.Width - layerBounds.X) + 0.5);
                int y = (int)(layerBounds.Height - (bounds.Y + bounds.Height - layerBounds.Y) + 0.5);

                // Make sure the value isn't greater than the maximum
                x = (int)Math.Min(x, layerBounds.Width - 1);
                y = (int)Math.Min(y, layerBounds.Height - 1);

                pos = new PointFx(x, y);
            }

            return(pos);
        }
Esempio n. 3
0
        /// <summary>
        /// Repaint from one of the camera's layers.
        /// </summary>
        /// <param name="bounds">The bounds to repaint, in view coordinates.</param>
        /// <param name="repaintedLayer">The layer that was repainted.</param>
        /// <remarks>
        /// The repaint region needs to be transformed from view to local coordinates in
        /// this case.  Unlike most repaint methods in piccolo this one must not modify
        /// the bounds parameter.
        /// </remarks>
        public virtual void RepaintFromLayer(RectangleFx bounds, PNode repaintedLayer)
        {
            bounds = ViewToLocal(bounds);
            bool boundsIntesects = Bounds.IntersectsWith(bounds);

            if (boundsIntesects)
            {
                RectangleFx tempRect = RectangleFxtensions.Intersect(bounds, Bounds);
                RepaintFrom(tempRect, repaintedLayer);
            }
        }
Esempio n. 4
0
 /// <summary>
 /// Overridden.  If the repaint request comes from a child, then
 /// repaint the intersection of the clip's bounds and the requested
 /// repaint bounds.
 /// </summary>
 /// <param name="bounds">
 /// The bounds to repaint, specified in the local coordinate system.
 /// </param>
 /// <param name="childOrThis">
 /// If childOrThis does not equal this then this node's matrix will
 /// be applied to the bounds paramater.
 /// </param>
 public override void RepaintFrom(RectangleFx bounds, PNode childOrThis)
 {
     if (childOrThis != this)
     {
         bounds = RectangleFxtensions.Intersect(Bounds, bounds);
         base.RepaintFrom(bounds, childOrThis);
     }
     else
     {
         base.RepaintFrom(bounds, childOrThis);
     }
 }
Esempio n. 5
0
        /// <summary>
        /// Pushes the current clip onto the clip stack and sets clip of the graphics context to
        /// the intersection of the current clip and the given clip.
        /// </summary>
        /// <remarks>
        /// The intersection of the current local clip and the new local clip is also pushed onto
        /// the local clip stack.
        /// </remarks>
        /// <param name="aClip">The clip to push.</param>
        public virtual void PushClip(RectangleFx aClip)
        {
            RectangleFx newLocalClip = RectangleFxtensions.Intersect(LocalClip, graphics.ClipBounds);

            localClipStack.Push(newLocalClip);

            //RegionFx currentClip = Graphics.Clip;
            RectangleFx currentClip = Graphics.ClipBounds;

            clipStack.Push(currentClip);
            //aClip = aClip.Clone();
            aClip.Intersects(currentClip);
            Graphics.ClipBounds = aClip;
        }
        public override void SetViewPosition(float x, float y)
        {
            if (camera != null)
            {
                // If a scroll is in progress - we ignore new scrolls -
                // if we didn't, since the scrollbars depend on the camera location
                // we can end up with an infinite loo
                if (!scrollInProgress)
                {
                    scrollInProgress = true;

                    // Get the union of all the layers' bounds
                    RectangleFx layerBounds = camera.UnionOfLayerFullBounds;

                    Matrix matrix = camera.ViewMatrix;
                    layerBounds = MatrixExtensions.Transform(matrix, layerBounds);

                    // Union the camera view bounds
                    RectangleFx viewBounds = camera.Bounds;
                    layerBounds = RectangleFxtensions.Union(layerBounds, viewBounds);

                    // Now find the new view position in view coordinates -
                    // This is basically the distance from the lower right
                    // corner of the window to the upper left corner of the
                    // document
                    // We then measure the offset from the lower right corner
                    // of the document
                    PointFx newPoint =
                        new PointFx(
                            layerBounds.X + layerBounds.Width - (x + viewBounds.Width),
                            layerBounds.Y + layerBounds.Height - (y + viewBounds.Height));

                    // Now transform the new view position into global coords
                    newPoint = camera.LocalToView(newPoint);

                    // Compute the new matrix values to put the camera at the
                    // correct location
                    float[] elements = MatrixExtensions.GetElements(matrix);
                    elements[4] = -(elements[0] * newPoint.X + elements[1] * newPoint.Y);
                    elements[5] = -(elements[2] * newPoint.X + elements[3] * newPoint.Y);

                    matrix = MatrixExtensions.SetElements(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]);

                    // Now actually set the camera's transform
                    camera.ViewMatrix = matrix;
                    scrollInProgress  = false;
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Caches the information necessary to animate from the current view bounds to the
        /// specified centerBounds
        /// </summary>
        /// <param name="centerBounds">The bounds to center the view on.</param>
        /// <param name="scaleToFit">
        /// Indicates whether the camera should scale it's view when necessary to fully fit
        /// the given bounds within the camera's view bounds.
        /// </param>
        /// <returns>The new view matrix to center the specified bounds.</returns>
        private Matrix CacheViewBounds(RectangleFx centerBounds, bool scaleToFit)
        {
            RectangleFx viewBounds = ViewBounds;

            // Initialize the image to the union of the current and destination bounds
            RectangleFx imageBounds = viewBounds;

            imageBounds = RectangleFxtensions.Union(imageBounds, centerBounds);

            AnimateViewToCenterBounds(imageBounds, scaleToFit, 0);

            imageAnimateBounds = ViewBounds;

            // Now create the actual cache image that we will use to animate fast

            System.Drawing.Image buffer = PaintBuffer;
            Color fBrush = Color.White;

            if (Brush != Color.Transparent)
            {
                fBrush = Brush;
            }
            ToImage(buffer, fBrush);

            // Do this after the painting above!
            imageAnimate = true;

            // Return the bounds to the previous viewbounds
            AnimateViewToCenterBounds(viewBounds, scaleToFit, 0);

            // The code below is just copied from animateViewToCenterBounds to create the
            // correct transform to center the specified bounds

            SizeFx delta     = PUtil.DeltaRequiredToCenter(viewBounds, centerBounds);
            Matrix newMatrix = ViewMatrix;

            newMatrix = MatrixExtensions.TranslateBy(newMatrix, delta.Width, delta.Height);

            if (scaleToFit)
            {
                float   s      = Math.Min(viewBounds.Width / centerBounds.Width, viewBounds.Height / centerBounds.Height);
                PointFx center = PUtil.CenterOfRectangle(centerBounds);
                newMatrix = MatrixExtensions.ScaleBy(newMatrix, s, center.X, center.Y);
            }

            return(newMatrix);
        }
Esempio n. 8
0
        /// <summary>
        /// Returns the union of the two rectangles.  If one rectangle is empty and one is not,
        /// the non-empty rectangle will be returned.
        /// </summary>
        /// <param name="rect1">The first rectangle.</param>
        /// <param name="rect2">The second rectangle.</param>
        /// <returns>The union of the two rectangles.</returns>
        public static RectangleFx AddRectToRect(RectangleFx rect1, RectangleFx rect2)
        {
            RectangleFx result = rect1;

            if (!result.IsEmpty)
            {
                if (!rect2.IsEmpty)
                {
                    result = RectangleFxtensions.Union(result, rect2);
                }
            }
            else
            {
                result = rect2;
            }

            return(result);
        }
        /// <summary>
        /// Sets the view position in a manner consistent with standardized scrolling.
        /// </summary>
        /// <param name="x">The x coordinate of the new position.</param>
        /// <param name="y">The y coordinate of the new position.</param>
        public virtual void SetViewPosition(float x, float y)
        {
            if (camera != null)
            {
                // Only process this scroll if a scroll is not already in progress;
                // otherwise, we could end up with an infinite loop, since the
                // scrollbars depend on the camera location.
                if (!scrollInProgress)
                {
                    scrollInProgress = true;

                    // Get the union of all the layers' bounds
                    RectangleFx layerBounds = UnionOfLayerFullBounds;

                    Matrix matrix = camera.ViewMatrix;
                    layerBounds = MatrixExtensions.Transform(matrix, layerBounds);

                    // Union the camera bounds
                    RectangleFx viewBounds = camera.Bounds;
                    layerBounds = RectangleFxtensions.Union(layerBounds, viewBounds);

                    // Now find the new view position in view coordinates
                    PointFx newPoint = new PointFx(layerBounds.X + x, layerBounds.Y + y);

                    // Now transform the new view position into global coords
                    newPoint = camera.LocalToView(newPoint);

                    // Compute the new matrix values to put the camera at the
                    // correct location
                    float[] elements = MatrixExtensions.GetElements(matrix);
                    elements[4] = -(elements[0] * newPoint.X + elements[1] * newPoint.Y);
                    elements[5] = -(elements[2] * newPoint.X + elements[3] * newPoint.Y);

                    matrix = MatrixExtensions.SetElements(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]);

                    // Now actually set the camera's transform
                    camera.ViewMatrix = matrix;
                    scrollInProgress  = false;
                }
            }
        }
        /// <summary>
        /// Gets the size of the view based on the specified camera bounds.
        /// </summary>
        /// <param name="bounds">The view bounds for which the view size will be computed.</param>
        /// <returns>The view size.</returns>
        public virtual SizeFx GetViewSize(RectangleFx bounds)
        {
            SizeFx size = SizeFx.Empty;

            if (camera != null)
            {
                // First we compute the union of all the layers
                RectangleFx layerBounds = UnionOfLayerFullBounds;

                // Then we put the bounds into camera coordinates and
                // union the camera bounds
                if (!layerBounds.IsEmpty)
                {
                    layerBounds = camera.ViewToLocal(layerBounds);
                }
                layerBounds = RectangleFxtensions.Union(layerBounds, bounds);

                size = new SizeFx((int)(layerBounds.Width + 0.5), (int)(layerBounds.Height + 0.5));
            }

            return(size);
        }
        /// <summary>
        /// Gets the view position given the specified camera bounds.
        /// </summary>
        /// <param name="bounds">
        /// The bounds for which the view position will be computed.
        /// </param>
        /// <returns>The view position.</returns>
        public virtual PointFx GetViewPosition(RectangleFx bounds)
        {
            PointFx pos = PointFx.Empty;

            if (camera != null)
            {
                // First we compute the union of all the layers
                RectangleFx layerBounds = UnionOfLayerFullBounds;

                // Then we put the bounds into camera coordinates and
                // union the camera bounds
                if (!layerBounds.IsEmpty)
                {
                    layerBounds = camera.ViewToLocal(layerBounds);
                }
                layerBounds = RectangleFxtensions.Union(layerBounds, bounds);

                pos = new PointFx((int)(bounds.X - layerBounds.X + 0.5), (int)(bounds.Y - layerBounds.Y + 0.5));
            }

            return(pos);
        }
Esempio n. 12
0
 /// <summary>
 /// Gets a rectangle centered on the given point and inflated in the x and y directions
 /// by the given amounts.
 /// </summary>
 /// <param name="aCenterPoint">The center point for the inflated rectangle.</param>
 /// <param name="inflateX">
 /// The amount to inflate the rectangle in the x direction.
 /// </param>
 /// <param name="inflateY">
 /// The amount to inflate the rectangle in the y direction.
 /// </param>
 /// <returns>The inflated rectangle.</returns>
 public static RectangleFx InflatedRectangle(PointFx aCenterPoint, float inflateX, float inflateY)
 {
     System.Drawing.RectangleF r = new System.Drawing.RectangleF(aCenterPoint.X, aCenterPoint.Y, 0, 0);
     r.Inflate(inflateX, inflateY);
     return(RectangleFxtensions.ToRectangleFx(r));
 }
Esempio n. 13
0
 /// <summary>
 /// Constructs a new PControl, wrapping the given
 /// <see cref="System.Windows.Forms.Control">System.Windows.Forms.Control</see> and
 /// setting the current canvas to the given canvas.
 /// </summary>
 /// <param name="control">The control to wrap.</param>
 /// <param name="currentCanvas">
 /// The canvas to add the control to when <see cref="Editing"/> is turned on.
 /// </param>
 public PControl(Control control, PCanvas currentCanvas)
 {
     this.control       = control;
     this.currentCanvas = currentCanvas;
     this.Bounds        = RectangleFxtensions.ToRectangleFx(control.Bounds);
 }