I suspect the titles of these last pair of articles are a touch misleading as they talk about extended zoom operations without actually describing a zoom process (as this is already part of other ImageBox articles. Unfortunately I can't really think of better titles and the theory is generic enough to be applied to any type of zooming, not just the ImageBox
.
My previous article touched on zooming in a ScrollableControl
while keeping the content correctly aligned to a fixed point, usually the mouse position prior to the zoom. This article expands on that with another new feature in the upcoming ImageBox
update, zooming to a given region. You've probably seen this behaviour in other paint programs, where you select a Zoom tool, draw a rectangle, and the document is automatically zoomed to fit.
Again, this is actually quite simple to achieve and this blog post is pretty much just a reference to me of how I did this so I don't forget next time I want something similar! We'll start off by quickly describing a method that I forgot to include in the previous post - CenterAt
. This simple method centers the view port on the given document location. This use useful for when you want to use ScrollTo
without providing a relative offset... or for centering the display on a selection rectangle.
publicvirtualvoid CenterAt(Point imageLocation) {this.ScrollTo(imageLocation, new Point(this.ClientSize.Width / 2, this.ClientSize.Height / 2)); }
Very straightforward, it simply calls ScrollTo
, using the center of the control as the offset. Now for the actual ZoomToRegion
method:
publicvirtualvoid ZoomToRegion(RectangleF rectangle) {double ratioX;double ratioY;int cx;int cy; ratioX = this.ClientSize.Width / rectangle.Width; ratioY = this.ClientSize.Height / rectangle.Height; cx = (int)(rectangle.X + (rectangle.Width / 2)); cy = (int)(rectangle.Y + (rectangle.Height / 2));this.Zoom = (int)(Math.Min(ratioX, ratioY) * 100);this.CenterAt(new Point(cx, cy)); }
This accepts a RectangleF
structure (you could use a Rectangle
, but then if you attempt to draw selection regions on a zoomed out document, rounding from float
to int
would render your selections useless), and it then calculates a new zoom factor and offset.
- First, the ration of the width and height of the region against the width and height of the view port is calculated
- We use the smallest ratio (to ensure if that everything you selected appears when the zoom is applied) to calculate the new zom level
- After this, we define the center of the rectangle
- With all the calculations done, we set the zoom level of the control
- And finally, we call our new
CenterAt
method to center the view port on the center of the source region
In the actual ImageBox
control, a new SelectionMode
has been added - Zoom
. As the name somewhat logically suggests, when this mode is active, after the user draws a selection rectangle, the control then zooms to match the rectangle they have drawn. This updated mode is called from the OnSelected
method, as follows:
if (this.SelectionRegion != null&& this.SelectionRegion.Width > ImageBox.SelectionDeadZone && this.SelectionRegion.Height > ImageBox.SelectionDeadZone) {this.ZoomToRegion(this.SelectionRegion);this.SelectionRegion = RectangleF.Empty; }
The mysterious ImageBox.SelectionDeadZone
field is a constant currently set to 5, and basically ensures the user selects a valid rectangle first - when I was testing the first iteration of this code, having the mouse wobble as you clicked the control was enough to generate a 1x1 rectangle, definitely not a good user experience!
The only disadvantage is this functionality only lends itself to zooming it, and not out.
All content Copyright © by Cyotek Ltd or its respective writers. Permission to reproduce news and web log entries and other RSS feed content in unmodified form without notice is granted provided they are not used to endorse or promote any products or opinions (other than what was expressed by the author) and without taking them out of context. Written permission from the copyright owner must be obtained for everything else.
Original URL of this content is http://www.cyotek.com/blog/zooming-to-fit-a-region-in-a-scrollablecontrol?source=rss