dotnet / dotnet/wpf

[API Proposal]: public Viewbox.ComputeScaleFactor

Open
#9,350 0 comments 0 reactions 0 assignees View on GitHub
API suggestion
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.