Skip to content

Commit

Permalink
Use custom cursor when dragging image.
Browse files Browse the repository at this point in the history
  • Loading branch information
hamster620 committed Jul 1, 2023
1 parent 49720df commit 460b033
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 5 deletions.
11 changes: 10 additions & 1 deletion PixelViewer/Controls/SessionControl.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,16 @@
<LayoutTransformControl ClipToBounds="False">
<Panel ClipToBounds="False">
<Image x:Name="image" DoubleTapped="OnImageDoubleTapped" Height="{Binding ImageDisplaySize.Height}" HorizontalAlignment="Center" PointerExited="OnImagePointerLeave" PointerMoved="OnImagePointerMoved" PointerPressed="OnImagePointerPressed" PointerReleased="OnImagePointerReleased" Source="{Binding $parent[UserControl].EffectiveRenderedImage}" VerticalAlignment="Center" Width="{Binding ImageDisplaySize.Width}"/>
<Border BorderBrush="{DynamicResource Brush/WorkingArea.Background}" BorderThickness="1" CornerRadius="2" Height="{Binding #root.SelectedImageDisplayPixelBounds.Height}" HorizontalAlignment="Left" IsHitTestVisible="False" IsVisible="{Binding #root.IsPointerOverImage}" VerticalAlignment="Top" Width="{Binding #root.SelectedImageDisplayPixelBounds.Width}">
<Border BorderBrush="{DynamicResource Brush/WorkingArea.Background}" BorderThickness="1" CornerRadius="2" Height="{Binding #root.SelectedImageDisplayPixelBounds.Height}" HorizontalAlignment="Left" IsHitTestVisible="False" VerticalAlignment="Top" Width="{Binding #root.SelectedImageDisplayPixelBounds.Width}">
<Border.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="IsPointerOverImage" ElementName="root"/>
<MultiBinding Converter="{x:Static BoolConverters.Or}">
<Binding Path="!IsImageViewerScrollable" ElementName="root"/>
<Binding Path="!IsPointerPressedOnImage" ElementName="root"/>
</MultiBinding>
</MultiBinding>
</Border.IsVisible>
<Border.RenderTransform>
<TranslateTransform X="{Binding #root.SelectedImageDisplayPixelBounds.X}" Y="{Binding #root.SelectedImageDisplayPixelBounds.Y}"/>
</Border.RenderTransform>
Expand Down
29 changes: 25 additions & 4 deletions PixelViewer/Controls/SessionControl.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class SessionControl : UserControl<IAppSuiteApplication>
// Static fields.
static readonly StyledProperty<IImage?> EffectiveRenderedImageProperty = AvaloniaProperty.Register<SessionControl, IImage?>(nameof(EffectiveRenderedImage));
static readonly StyledProperty<BitmapInterpolationMode> EffectiveRenderedImageInterpolationModeProperty = AvaloniaProperty.Register<SessionControl, BitmapInterpolationMode>(nameof(EffectiveRenderedImageInterpolationMode), BitmapInterpolationMode.None);
static Cursor? ImageDraggingCursor;
static readonly StyledProperty<bool> IsImageViewerScrollableProperty = AvaloniaProperty.Register<SessionControl, bool>(nameof(IsImageViewerScrollable));
static readonly StyledProperty<bool> IsPointerOverImageProperty = AvaloniaProperty.Register<SessionControl, bool>("IsPointerOverImage");
static readonly StyledProperty<bool> IsPointerPressedOnBrightnessAdjustmentUIProperty = AvaloniaProperty.Register<SessionControl, bool>("IsPointerPressedOnBrightnessAdjustmentUI");
Expand Down Expand Up @@ -508,12 +509,14 @@ void SetupFilterParamsSliderAndButtons(string name, int group)
if (this.GetValue(IsPointerPressedOnImageProperty)
&& this.IsImageViewerScrollable)
{
cursorType = StandardCursorType.SizeAll;
ImageDraggingCursor ??= LoadCursor("Image/Cursor.Hand");
this.image.Cursor = ImageDraggingCursor;
return;
}
else
cursorType = StandardCursorType.None;
cursorType = StandardCursorType.None;
}
if (this.imageCursorType != cursorType)
if (this.imageCursorType != cursorType
|| this.image.Cursor == ImageDraggingCursor)
{
this.imageCursorType = cursorType;
this.image.Cursor = new Cursor(cursorType);
Expand Down Expand Up @@ -724,6 +727,24 @@ void IncreaseSliderValue(Slider slider)

// Check whether image viewer is scrollable in current state or not.
bool IsImageViewerScrollable => this.GetValue(IsImageViewerScrollableProperty);


// Load cursor from resource.
static Cursor LoadCursor(string resourceKey)
{
var image = App.Current.FindResourceOrDefault<IImage?>(resourceKey) ?? throw new ArgumentException();
var imageSize = image.Size;
var maxSide = App.Current.FindResourceOrDefault("Double/Cursor.MaxSide", 30.0);
var scaleX = maxSide / imageSize.Width;
var scaleY = maxSide / imageSize.Height;
var scale = Math.Min(scaleX, scaleY);
var cursorWidth = (int)(imageSize.Width * scale + 0.5);
var cursorHeight = (int)(imageSize.Height * scale + 0.5);
var cursorBitmap = new RenderTargetBitmap(new(cursorWidth, cursorHeight));
using var cursorDrawingContext = cursorBitmap.CreateDrawingContext();
image.Draw(cursorDrawingContext, new(default, imageSize), new(0, 0, cursorWidth, cursorHeight));
return new(cursorBitmap, new(cursorWidth >> 1, cursorHeight >> 1));
}


/// <summary>
Expand Down
3 changes: 3 additions & 0 deletions PixelViewer/Styles/Base.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
<!-- ColorSpaceInfoDialog -->
<sys:Double x:Key="Double/ColorSpaceInfoDialog.Width">900</sys:Double>
<Thickness x:Key="Thickness/ColorSpaceInfoDialog.RightContentPanel.Padding">10,20,30,20</Thickness>

<!-- Cursor -->
<sys:Double x:Key="Double/Cursor.MaxSide">16</sys:Double>

<!-- FrameNumberSelectionDialog -->
<sys:Double x:Key="Double/FrameNumberSelectionDialog.Width">300</sys:Double>
Expand Down
13 changes: 13 additions & 0 deletions PixelViewer/Styles/Icons.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,19 @@
<GeometryDrawing x:Key="Drawing/Icon.RotateRight" Brush="{DynamicResource Brush/Icon}" Geometry="{StaticResource Geometry/Icon.RotateRight}"/>

<!-- Images -->

<!-- MIT License: https://www.svgrepo.com/page/licensing#MIT -->
<DrawingImage x:Key="Image/Cursor.Hand">
<DrawingGroup>
<GeometryDrawing Brush="#ffffff" Geometry="F1 M10 10.5L10 6C10 4.89543 9.10457 4 8 4L8 4C6.89543 4 6 4.89543 6 6L6 14L7 15L5.24 13.24C4.45109 12.5226 3.23807 12.5503 2.48272 13.303C1.72738 14.0556 1.69538 15.2686 2.41 16.06L6.01 19.66C7.5 21.14 9.2 22 12 22L14 22C18.4183 22 22 18.4183 22 14L22 8C22 6.89543 21.1046 6 20 6C18.8954 6 18 6.89543 18 8L18 11L18 6C18 4.89543 17.1046 4 16 4L16 4C14.8954 4 14 4.89543 14 6L14 6L14 10L14 4C14 2.89543 13.1046 2 12 2L12 2C10.8954 2 10 2.89543 10 4L10 6" />
<GeometryDrawing Geometry="F1 M10 10.5L10 6C10 4.89543 9.10457 4 8 4L8 4C6.89543 4 6 4.89543 6 6L6 14L7 15L5.24 13.24C4.45109 12.5226 3.23807 12.5503 2.48272 13.303C1.72738 14.0556 1.69538 15.2686 2.41 16.06L6.01 19.66C7.5 21.14 9.2 22 12 22L14 22C18.4183 22 22 18.4183 22 14L22 8C22 6.89543 21.1046 6 20 6C18.8954 6 18 6.89543 18 8L18 11L18 6C18 4.89543 17.1046 4 16 4L16 4C14.8954 4 14 4.89543 14 6L14 6L14 10L14 4C14 2.89543 13.1046 2 12 2L12 2C10.8954 2 10 2.89543 10 4L10 6">
<GeometryDrawing.Pen>
<Pen Brush="#000000"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage>

<DrawingImage x:Key="Image/Icon.Alignment.Horizontal">
<GeometryDrawing Brush="{DynamicResource Brush/Icon}" Geometry="{StaticResource Geometry/Icon.Alignment.Horizontal}"/>
</DrawingImage>
Expand Down

0 comments on commit 460b033

Please sign in to comment.