[API Proposal]: public Viewbox.ComputeScaleFactor
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
### Background and motivation
Any code using the `Stretch` (and `StretchDirection`) property has to figure out how to scale the content respecting these properties, and how to undo the scaling when mapping coordinates back to the content. From built-in controls, this includes `Image`, `MediaElement`, `Viewbox` and `DocumentPageView` which all call a helper method to calculate the scaling.
It would be beneficial to other developers to be able to reuse the code for consistent results including corner cases (such as infinities and near-zero values).
### API Proposal
```diff
namespace System.Windows.Controls;
public class Viewbox
{
- internal static Size ComputeScaleFactor(Size availableSize, Size contentSize, Stretch stretch, StretchDirection stretchDirection);
+ public static Size ComputeScaleFactor(Size availableSize, Size contentSize, Stretch stretch, StretchDirection stretchDirection);
}
```
### API Usage
```C#
void Image_MouseLeftButtonDown(MouseButtonEventArgs e)
{
Point point = e.GetPosition(this);
Size stretchScale = ComputeScaleFactor(RenderSize, new Size(Source.Width, Source.Height), Stretch, StretchDirection);
Point pixelPoint = new Point(point.X / stretchScale.Width, point.Y / stretchScale.Height); // click in image source coordinates
...
}
```
### Alternative Designs
The final scaling transform could be made available as a `ScaleTransform` instead. This would provide more robust solution with invertability and built-in ability to transform points and bounds, but with higher computational and memory costs. This could either be a new constructor, such as
```c#
public ScaleTransform(Size availableSize, Size contentSize, Stretch stretch, StretchDirection stretchDirection)
```
or a static method such as
```C#
public static ScaleTransform FromStretch(Size availableSize, Size contentSize, Stretch stretch, StretchDirection stretchDirection)
```
The `Viewbox` itself creates a `ScaleTransform` with the calculated values and uses it as a visual transform on the child.
Yet more alternatively, there could just be a `TranslatePoint` method somewhere (like `UIElement` or `Viewbox`), but that would have to calculate the scaling each time, which isn't great for usage in mouse move etc.
### Risks
No existing API surface is changed or removed, so there shouldn't be breaking changes. The code to calculate the scaling already exists as an internal method.
Contributor guide
Assessment
This issue has not been assessed yet.