Skip to content

Commit

Permalink
chore: merge with main
Browse files Browse the repository at this point in the history
  • Loading branch information
rajamatt committed Feb 25, 2025
2 parents 7208ac3 + 0498325 commit a831612
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 22 deletions.
4 changes: 1 addition & 3 deletions doc/controls/NavigationBar.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,6 @@ If no `MainCommand` is provided in the XAML, the `NavigationBar` will render the

`MainCommand` is typically used for customizing the back button, displaying a different icon, and/or invoking some type of custom action other than back navigation when clicked.

On **Android**, only icons are supported (`AppBarButton.Icon`). This is due to a platform limitation, which can be explained by the fact that `NavigationBar.Content` is left-aligned.

> [!NOTE]
> The default back button icon can be customized for non-mobile platforms by overriding the `NavigationBarBackIconData` resource. On `Android` and `iOS`, the native default back button icon is used. On Windows and other non-mobile platforms, you can provide a custom back button icon by defining the `NavigationBarBackIconData` resource in your resource dictionary:
>
Expand Down Expand Up @@ -551,7 +549,7 @@ Gets or sets the graphic content of the `AppBarButton`

Remarks:

* On **Android** and **iOS**, the `MainCommand` Icon only supports `BitmapIcon`s. `PrimaryCommands` and `SecondaryCommands` support any `IconElement` type.
* On **Android**, the `MainCommand` Icon only supports `BitmapIcon`s. `PrimaryCommands` and `SecondaryCommands` support any `IconElement` type.

### Recommended icon sizes (by scale)

Expand Down
51 changes: 51 additions & 0 deletions doc/controls/ZoomContentControl.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,54 @@ xmlns:utu="using:Uno.Toolkit.UI"
| ----------------- | ----------- | ----------------------------------------------------------------------------------------- |
| `FitToCanvas()` | `void` | Adjust the zoom level so that the content fits within the available space. |
| `ResetViewport()` | `void` | Resets the zoom level and panning offset to their default values and centers the content. |

### Usage

Below are the built-in interactions for ZoomContentControl usage. For these interactions to work, ensure the control is:

1. Visible and loaded (`IsLoaded` is true).
2. Active (`IsActive` = true).
3. Zooming and/or panning is allowed (`IsZoomAllowed`/`IsPanAllowed` = true).

#### Zooming (Ctrl + Mouse Wheel)

Ctrl + Mouse Wheel: Zoom in/out around the current cursor position.
The `ScaleWheelRatio` property controls how quickly the zoom factor changes per mouse wheel tick.

#### Scrolling (Mouse Wheel)

Mouse Wheel by itself scrolls vertically.
Shift + Mouse Wheel scrolls horizontally.
The `PanWheelRatio` property determines how many pixels to move per mouse wheel tick.

#### Panning (Middle-Click + Drag)

Press and hold the middle button.
Drag to move the content.
Release the mouse button to stop panning.

#### Programmatic Control

Beyond user interactions, you can control zoom and pan directly:

`FitToCanvas()`: Automatically sizes the content so it fits the entire available space.
`ResetViewport()`: Resets both zoom level and offset to their defaults (zoom = 1, scroll offsets = 0).

### Advanced Usage: Overriding Pointer Methods

ZoomContentControl does not subscribe to pointer events directly. Instead, it overrides the base OnPointer methods. This lets you derive from ZoomContentControl and fully customize pointer handling in your subclass. For example:

```csharp
public class MyCustomZoomControl : ZoomContentControl
{
protected override void OnPointerPressed(PointerRoutedEventArgs e)
{
// Skip or extend default behavior:
// base.OnPointerPressed(e);
// Implement your own pointer logic here...
}
}
```

If you do not call `base.OnPointerPressed(e)`, you bypass the built-in pan/zoom logic entirely. This approach lets you disable or alter parts of the default pointer behavior without modifying the original code.
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ protected override void Render()

// Foreground
var hasIconColor = element.TryGetIconColor(out var foregroundColor);
var foregroundOpacity = hasIconColor ? foregroundColor.A / 255d : 0d;
var foregroundOpacity = hasIconColor ? foregroundColor.A / 255d : 1.0;

// Visibility
if (element.Visibility == Visibility.Visible)
Expand Down
2 changes: 2 additions & 0 deletions src/Uno.Toolkit.UI/Controls/NavigationBar/NavigationBar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -1478,7 +1478,9 @@
TargetType="utu:NavigationBar">
<Border BorderThickness="{TemplateBinding Padding}"
Background="{TemplateBinding Background}">
<!-- Setting Content to null to avoid the implicit binding to Content on the NativeNavigationBarPresenter -->
<utu:NativeNavigationBarPresenter x:Name="NavigationBarPresenter"
Content="{x:Null}"
Height="44" />
<!-- TODO: 1px line -->
</Border>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,10 @@ protected override void Render()
backButtonAppearance.Normal.TitleTextAttributes = attributes;
backButtonAppearance.Highlighted.TitleTextAttributes = attributes;

backImage = backImage?.ApplyTintColor(foreground);
if (mainCommand is { } && mainCommand.TryGetIconColor(out var _))
{
backImage = backImage?.ApplyTintColor(foregroundColor);
}
}

if (backImage is { })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@ public ZoomContentControl()
DefaultStyleKey = typeof(ZoomContentControl);

SizeChanged += OnSizeChanged;
PointerPressed += OnPointerPressed;
PointerReleased += OnPointerReleased;
PointerMoved += OnPointerMoved;
PointerWheelChanged += OnPointerWheelChanged;
}

protected override void OnApplyTemplate()
Expand Down Expand Up @@ -275,8 +271,10 @@ private void OnSizeChanged(object sender, SizeChangedEventArgs args)
}
}

private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
protected override void OnPointerPressed(PointerRoutedEventArgs e)
{
base.OnPointerPressed(e);

if (!IsAllowedToWork || _translation is null) return;
var pointerPoint = e.GetCurrentPoint(this);
var pointerProperties = pointerPoint.Properties;
Expand Down Expand Up @@ -306,15 +304,19 @@ private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
}
}

private void OnPointerReleased(object sender, PointerRoutedEventArgs e)
protected override void OnPointerReleased(PointerRoutedEventArgs e)
{
base.OnPointerReleased(e);

ReleasePointerCaptures();
_capturedPointerContext = default;
}

private void OnPointerMoved(object sender, PointerRoutedEventArgs e)
protected override void OnPointerMoved(PointerRoutedEventArgs e)
{
if (!IsAllowedToWork ||!IsPanAllowed) return;
base.OnPointerMoved(e);

if (!IsAllowedToWork || !IsPanAllowed) return;

if (_capturedPointerContext is { } context)
{
Expand All @@ -326,8 +328,10 @@ private void OnPointerMoved(object sender, PointerRoutedEventArgs e)
}
}

private void OnPointerWheelChanged(object sender, PointerRoutedEventArgs e)
protected override void OnPointerWheelChanged(PointerRoutedEventArgs e)
{
base.OnPointerWheelChanged(e);

if (!IsAllowedToWork) return;
if (Viewport is not { } vp) return;

Expand Down
6 changes: 0 additions & 6 deletions src/Uno.Toolkit.UI/Extensions/AppBarButtonExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,6 @@ public static bool TryGetIconColor(this AppBarButton appBarButton, out Color ico
return true;
}

if (ColorHelper.TryGetColorWithOpacity(appBarButton.Foreground, out var buttonForeground))
{
iconColor = buttonForeground;
return true;
}

return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,7 @@
HorizontalAlignment="Center">
<!-- UNO WORKAROUND: The ViewBox center should be horizontal Stretch but the Grid aligns the content left -->
<Viewbox x:Name="ContentViewbox"
MaxHeight="{ThemeResource NavBarMainCommandAppBarButtonContentHeight}"
MaxWidth="{ThemeResource NavBarMainCommandAppBarButtonContentHeight}"
Height="{ThemeResource NavBarAppBarButtonContentHeight}"
Visibility="{Binding Path=Icon, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource NullToCollapsedConverter}}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Expand Down Expand Up @@ -1275,7 +1274,9 @@
TargetType="utu:NavigationBar">
<Border BorderThickness="{TemplateBinding Padding}"
Background="{TemplateBinding Background}">
<!-- Setting Content to null to avoid the implicit binding to Content on the NativeNavigationBarPresenter -->
<utu:NativeNavigationBarPresenter x:Name="NavigationBarPresenter"
Content="{x:Null}"
Height="44" />
</Border>
</ios:ControlTemplate>
Expand Down

0 comments on commit a831612

Please sign in to comment.