1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Added rotating rotation cursors (think about that one for a sec!)

This commit is contained in:
Robert 2020-01-28 19:51:43 +01:00
parent c3a11386b4
commit 19bbef4cad
10 changed files with 168 additions and 5 deletions

View File

@ -224,6 +224,7 @@
<Compile Include="Services\Interfaces\IProfileEditorService.cs" />
<Compile Include="Services\LayerShapeService.cs" />
<Compile Include="Services\ProfileEditorService.cs" />
<Compile Include="Utilities\CursorRotator.cs" />
<Compile Include="Utilities\ThemeWatcher.cs" />
<Compile Include="Behaviors\TreeViewSelectionBehavior.cs" />
<Compile Include="Utilities\TriggerTracing.cs" />
@ -570,6 +571,18 @@
<ItemGroup>
<Folder Include="Ninject\Providers\" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\aero_rotate_bl_ico.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\aero_rotate_br_ico.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\aero_rotate_tl_ico.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\aero_rotate_tr_ico.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>

View File

@ -150,6 +150,16 @@ namespace Artemis.UI.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
internal static System.Drawing.Icon aero_rotate_bl_ico {
get {
object obj = ResourceManager.GetObject("aero_rotate_bl_ico", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
@ -160,6 +170,16 @@ namespace Artemis.UI.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
internal static System.Drawing.Icon aero_rotate_br_ico {
get {
object obj = ResourceManager.GetObject("aero_rotate_br_ico", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
@ -170,6 +190,16 @@ namespace Artemis.UI.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
internal static System.Drawing.Icon aero_rotate_tl_ico {
get {
object obj = ResourceManager.GetObject("aero_rotate_tl_ico", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
@ -180,6 +210,16 @@ namespace Artemis.UI.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
internal static System.Drawing.Icon aero_rotate_tr_ico {
get {
object obj = ResourceManager.GetObject("aero_rotate_tr_ico", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>

View File

@ -145,15 +145,27 @@
<data name="aero_rotate_bl" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\aero_rotate_bl.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="aero_rotate_bl_ico" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\aero_rotate_bl_ico.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="aero_rotate_br" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\aero_rotate_br.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="aero_rotate_br_ico" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\aero_rotate_br_ico.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="aero_rotate_tl" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\aero_rotate_tl.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="aero_rotate_tl_ico" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\aero_rotate_tl_ico.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="aero_rotate_tr" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\aero_rotate_tr.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="aero_rotate_tr_ico" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\aero_rotate_tr_ico.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="bow" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\bow.svg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -19,28 +19,28 @@
Canvas.Left="{Binding TopLeft.X}"
Canvas.Top="{Binding TopLeft.Y}"
Fill="Transparent"
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="Cross" />
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="{Binding TopLeftRotateCursor}" />
<Ellipse Width="{Binding RotateSize}"
Height="{Binding RotateSize}"
Margin="{Binding RotateOffset}"
Canvas.Left="{Binding TopRight.X}"
Canvas.Top="{Binding TopRight.Y}"
Fill="Transparent"
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="Cross" />
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="{Binding TopRightRotateCursor}" />
<Ellipse Width="{Binding RotateSize}"
Height="{Binding RotateSize}"
Margin="{Binding RotateOffset}"
Canvas.Left="{Binding BottomRight.X}"
Canvas.Top="{Binding BottomRight.Y}"
Fill="Transparent"
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="Cross" />
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="{Binding BottomRightRotateCursor}" />
<Ellipse Width="{Binding RotateSize}"
Height="{Binding RotateSize}"
Margin="{Binding RotateOffset}"
Canvas.Left="{Binding BottomLeft.X}"
Canvas.Top="{Binding BottomLeft.Y}"
Fill="Transparent"
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="Cross" />
MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="{Binding BottomLeftRotateCursor}" />
<!-- The part of the layer's shape that is inside the layer -->
<Path Data="{Binding ShapeGeometry, Mode=OneWay}"
Fill="Transparent"

View File

@ -4,8 +4,10 @@ using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using Artemis.Core.Models.Profile;
using Artemis.UI.Properties;
using Artemis.UI.Services;
using Artemis.UI.Services.Interfaces;
using Artemis.UI.Utilities;
using SkiaSharp;
using SkiaSharp.Views.WPF;
using Stylet;
@ -60,6 +62,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
public SKPoint BottomCenter { get; set; }
public SKPoint LeftCenter { get; set; }
public Cursor TopLeftRotateCursor { get; set; }
public Cursor TopRightRotateCursor { get; set; }
public Cursor BottomRightRotateCursor { get; set; }
public Cursor BottomLeftRotateCursor { get; set; }
private void Update()
{
if (!(ProfileEditorService.SelectedProfileElement is Layer layer))
@ -80,6 +87,11 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
BottomCenter = new SKPoint((BottomLeft.X + BottomRight.X) / 2, (BottomLeft.Y + BottomRight.Y) / 2);
LeftCenter = new SKPoint((TopLeft.X + BottomLeft.X) / 2, (TopLeft.Y + BottomLeft.Y) / 2);
TopLeftRotateCursor = CursorUtilities.GetRotatedCursor(Resources.aero_rotate_tl_ico, layer.RotationProperty.CurrentValue);
TopRightRotateCursor = CursorUtilities.GetRotatedCursor(Resources.aero_rotate_tr_ico, layer.RotationProperty.CurrentValue);
BottomRightRotateCursor = CursorUtilities.GetRotatedCursor(Resources.aero_rotate_br_ico, layer.RotationProperty.CurrentValue);
BottomLeftRotateCursor = CursorUtilities.GetRotatedCursor(Resources.aero_rotate_bl_ico, layer.RotationProperty.CurrentValue);
Execute.PostToUIThread(() =>
{
var shapeGeometry = new RectangleGeometry(_layerEditorService.GetShapeRenderRect(layer.LayerShape))
@ -92,7 +104,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization.Tools
ShapeTransformCollection.Freeze();
});
}
private void UpdateControls()
{
ControlSize = Math.Max(10 / ProfileViewModel.PanZoomViewModel.Zoom, 4);

View File

@ -0,0 +1,86 @@
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Input;
namespace Artemis.UI.Utilities
{
public static class CursorUtilities
{
public static Cursor GetRotatedCursor(Icon icon, float rotationAngle)
{
// Load as Bitmap, convert to BitmapSource
using (var iconStream = new MemoryStream())
using (var rotatedStream = new MemoryStream())
{
icon.Save(iconStream);
// Open the source image and create the bitmap for the rotated image
using (var sourceImage = icon.ToBitmap())
using (var rotateImage = new Bitmap(sourceImage.Width, sourceImage.Height))
{
// Set the resolution for the rotation image
rotateImage.SetResolution(sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
// Create a graphics object
using (var gdi = Graphics.FromImage(rotateImage))
{
//Rotate the image
gdi.TranslateTransform((float) sourceImage.Width / 2, (float) sourceImage.Height / 2);
gdi.RotateTransform(rotationAngle);
gdi.TranslateTransform(-(float) sourceImage.Width / 2, -(float) sourceImage.Height / 2);
gdi.DrawImage(sourceImage, new Point(0, 0));
}
// Save to a file
IconFromImage(rotateImage).Save(rotatedStream);
}
// Convert saved file into .cur format
rotatedStream.Seek(2, SeekOrigin.Begin);
rotatedStream.Write(iconStream.ToArray(), 2, 1);
rotatedStream.Seek(10, SeekOrigin.Begin);
rotatedStream.Write(iconStream.ToArray(), 10, 2);
rotatedStream.Seek(0, SeekOrigin.Begin);
// Construct Cursor
return new Cursor(rotatedStream);
}
}
public static Icon IconFromImage(Image img)
{
using (var ms = new MemoryStream())
using (var bw = new BinaryWriter(ms))
{
// Header
bw.Write((short) 0); // 0 : reserved
bw.Write((short) 1); // 2 : 1=ico, 2=cur
bw.Write((short) 1); // 4 : number of images
// Image directory
var w = img.Width;
if (w >= 256) w = 0;
bw.Write((byte) w); // 0 : width of image
var h = img.Height;
if (h >= 256) h = 0;
bw.Write((byte) h); // 1 : height of image
bw.Write((byte) 0); // 2 : number of colors in palette
bw.Write((byte) 0); // 3 : reserved
bw.Write((short) 0); // 4 : number of color planes
bw.Write((short) 0); // 6 : bits per pixel
var sizeHere = ms.Position;
bw.Write(0); // 8 : image size
var start = (int) ms.Position + 4;
bw.Write(start); // 12: offset of image data
// Image data
img.Save(ms, ImageFormat.Png);
var imageSize = (int) ms.Position - start;
ms.Seek(sizeHere, SeekOrigin.Begin);
bw.Write(imageSize);
ms.Seek(0, SeekOrigin.Begin);
// And load it
return new Icon(ms);
}
}
}
}