diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 481cff2a0..0837eb5af 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -224,6 +224,7 @@ + @@ -570,6 +571,18 @@ + + + + + + + + + + + + diff --git a/src/Artemis.UI/Properties/Resources.Designer.cs b/src/Artemis.UI/Properties/Resources.Designer.cs index 0b1cc4c0d..2c6653c37 100644 --- a/src/Artemis.UI/Properties/Resources.Designer.cs +++ b/src/Artemis.UI/Properties/Resources.Designer.cs @@ -150,6 +150,16 @@ namespace Artemis.UI.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon aero_rotate_bl_ico { + get { + object obj = ResourceManager.GetObject("aero_rotate_bl_ico", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -160,6 +170,16 @@ namespace Artemis.UI.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon aero_rotate_br_ico { + get { + object obj = ResourceManager.GetObject("aero_rotate_br_ico", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -170,6 +190,16 @@ namespace Artemis.UI.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon aero_rotate_tl_ico { + get { + object obj = ResourceManager.GetObject("aero_rotate_tl_ico", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -180,6 +210,16 @@ namespace Artemis.UI.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon aero_rotate_tr_ico { + get { + object obj = ResourceManager.GetObject("aero_rotate_tr_ico", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// diff --git a/src/Artemis.UI/Properties/Resources.resx b/src/Artemis.UI/Properties/Resources.resx index 980545d14..b89137361 100644 --- a/src/Artemis.UI/Properties/Resources.resx +++ b/src/Artemis.UI/Properties/Resources.resx @@ -145,15 +145,27 @@ ..\Resources\aero_rotate_bl.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\aero_rotate_bl_ico.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\aero_rotate_br.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\aero_rotate_br_ico.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\aero_rotate_tl.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\aero_rotate_tl_ico.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\aero_rotate_tr.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\aero_rotate_tr_ico.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\bow.svg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/src/Artemis.UI/Resources/aero_rotate_bl_ico.ico b/src/Artemis.UI/Resources/aero_rotate_bl_ico.ico new file mode 100644 index 000000000..ec5dce665 Binary files /dev/null and b/src/Artemis.UI/Resources/aero_rotate_bl_ico.ico differ diff --git a/src/Artemis.UI/Resources/aero_rotate_br_ico.ico b/src/Artemis.UI/Resources/aero_rotate_br_ico.ico new file mode 100644 index 000000000..1a02fb2b9 Binary files /dev/null and b/src/Artemis.UI/Resources/aero_rotate_br_ico.ico differ diff --git a/src/Artemis.UI/Resources/aero_rotate_tl_ico.ico b/src/Artemis.UI/Resources/aero_rotate_tl_ico.ico new file mode 100644 index 000000000..cfbbaca47 Binary files /dev/null and b/src/Artemis.UI/Resources/aero_rotate_tl_ico.ico differ diff --git a/src/Artemis.UI/Resources/aero_rotate_tr_ico.ico b/src/Artemis.UI/Resources/aero_rotate_tr_ico.ico new file mode 100644 index 000000000..43b9d02b0 Binary files /dev/null and b/src/Artemis.UI/Resources/aero_rotate_tr_ico.ico differ diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolView.xaml index 376440aa6..6f3166fbf 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/Tools/EditToolView.xaml @@ -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}" /> + MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="{Binding TopRightRotateCursor}" /> + MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="{Binding BottomRightRotateCursor}" /> + MouseDown="{s:Action ShapeEditMouseDown}" MouseUp="{s:Action ShapeEditMouseUp}" MouseMove="{s:Action Rotate}" Cursor="{Binding BottomLeftRotateCursor}" /> { 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); diff --git a/src/Artemis.UI/Utilities/CursorRotator.cs b/src/Artemis.UI/Utilities/CursorRotator.cs new file mode 100644 index 000000000..df9a77e1d --- /dev/null +++ b/src/Artemis.UI/Utilities/CursorRotator.cs @@ -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); + } + } + } +} \ No newline at end of file