/// <summary>
        /// Sets scroll and zoom to center the given rectangle in the client area with a given scale</summary>
        /// <param name="adapter">Adapter managing transform</param>
        /// <param name="scale">Scale</param>
        /// <param name="itemBounds">Rectangle to frame, in client coordinates</param>
        /// <param name="clientBounds">Client area</param>
        public static void ZoomAboutCenter(this ITransformAdapter adapter, Point scale, Rect itemBounds, Rect clientBounds)
        {
            if (adapter == null || !adapter.Transform.HasInverse || itemBounds.IsEmpty)
            {
                return;
            }

            Rect worldBounds = MathUtil.InverseTransform(adapter.Transform, itemBounds);

            if (adapter.UniformScale)
            {
                scale.X = scale.Y = Math.Min(scale.X, scale.Y);
            }

            scale = adapter.ConstrainScale(scale);

            // calculate translation needed to put bounds center at center of view
            Point worldBoundsCenter = new Point(
                worldBounds.X + worldBounds.Width / 2,
                worldBounds.Y + worldBounds.Height / 2);

            Point translation = new Point(
                clientBounds.Width / 2 - worldBoundsCenter.X * scale.X,
                clientBounds.Height / 2 - worldBoundsCenter.Y * scale.Y);

            adapter.SetTransform(scale.X, scale.Y, translation.X, translation.Y);
        }
        /// <summary>
        /// Sets scroll and zoom so that the largest axis of the given rectangle almost
        /// fills the client area</summary>
        /// <param name="adapter">Adapter managing transform</param>
        /// <param name="itemBounds">Rectangle to frame, in client coordinates</param>
        /// <param name="clientBounds">Client area</param>
        public static void Frame(this ITransformAdapter adapter, Rect itemBounds, Rect clientBounds)
        {
            if (adapter == null || itemBounds.IsEmpty || !adapter.Transform.HasInverse)
            {
                return;
            }

            Rect worldBounds = MathUtil.InverseTransform(adapter.Transform, itemBounds);

            // calculate scale so bounding rectangle (in world coordinates) fills client
            // rectangle with some margin around the edges
            const double MarginScale = 0.86;
            Point        scale       = new Point(
                Math.Abs(clientBounds.Width / worldBounds.Width) * MarginScale,
                Math.Abs(clientBounds.Height / worldBounds.Height) * MarginScale);

            if (adapter.UniformScale)
            {
                scale.X = scale.Y = Math.Min(scale.X, scale.Y);
            }

            scale = adapter.ConstrainScale(scale);

            // calculate translation needed to put bounds center at center of view
            Point worldBoundsCenter = new Point(
                worldBounds.X + worldBounds.Width / 2,
                worldBounds.Y + worldBounds.Height / 2);

            Point translation = new Point(
                (clientBounds.Width / 2 - worldBoundsCenter.X * scale.X),
                (clientBounds.Height / 2 - worldBoundsCenter.Y * scale.Y));

            adapter.SetTransform(scale.X, scale.Y, translation.X, translation.Y);
        }
Example #3
0
        /// <summary>
        /// Sets scroll and zoom so that the largest axis of the given rectangle almost
        /// fills the client area</summary>
        /// <param name="adapter">Adapter managing transform</param>
        /// <param name="bounds">Rectangle to frame, in Windows client coordinates</param>
        public static void Frame(this ITransformAdapter adapter, RectangleF bounds)
        {
            if (bounds.IsEmpty)
            {
                return;
            }

            RectangleF worldBounds = GdiUtil.InverseTransform(adapter.Transform, bounds);

            // calculate scale so bounding rectangle (in world coordinates) fills client
            //  rectangle with some margin around the edges
            RectangleF  clientRect  = adapter.AdaptedControl.ClientRectangle;
            const float MarginScale = 0.86f;
            PointF      scale       = new PointF(
                Math.Abs(clientRect.Width / worldBounds.Width) * MarginScale,
                Math.Abs(clientRect.Height / worldBounds.Height) * MarginScale);

            if (adapter.UniformScale)
            {
                scale.X = scale.Y = Math.Min(scale.X, scale.Y);
            }

            scale = adapter.ConstrainScale(scale);

            // calculate translation needed to put bounds center at center of view
            PointF worldBoundsCenter = new PointF(
                worldBounds.X + worldBounds.Width / 2,
                worldBounds.Y + worldBounds.Height / 2);

            PointF translation = new PointF(
                clientRect.Width / 2 - worldBoundsCenter.X * scale.X,
                clientRect.Height / 2 - worldBoundsCenter.Y * scale.Y);

            adapter.SetTransform(
                scale.X,
                scale.Y,
                translation.X,
                translation.Y);
        }