Permalink
Browse files

Merge branch 'master' of github.com:PintaProject/Pinta

  • Loading branch information...
2 parents 31a40c5 + 3c76ce6 commit b63054c4c2c9b216ec94b7bd14caa940b52b6cb7 @robpvn robpvn committed Jan 24, 2012
@@ -69,7 +69,7 @@ public LayerActions ()
ImportFromFile = new Gtk.Action ("ImportFromFile", Catalog.GetString ("Import from File..."), null, "Menu.Layers.ImportFromFile.png");
FlipHorizontal = new Gtk.Action ("FlipHorizontal", Catalog.GetString ("Flip Horizontal"), null, "Menu.Layers.FlipHorizontal.png");
FlipVertical = new Gtk.Action ("FlipVertical", Catalog.GetString ("Flip Vertical"), null, "Menu.Layers.FlipVertical.png");
- RotateZoom = new Gtk.Action ("RotateZoom", Catalog.GetString ("Rotate / Zoom"), null, "Menu.Layers.RotateZoom.png");
+ RotateZoom = new Gtk.Action ("RotateZoom", Catalog.GetString ("Rotate / Zoom Layer..."), null, "Menu.Layers.RotateZoom.png");
MoveLayerUp = new Gtk.Action ("MoveLayerUp", Catalog.GetString ("Move Layer Up"), null, "Menu.Layers.MoveLayerUp.png");
MoveLayerDown = new Gtk.Action ("MoveLayerDown", Catalog.GetString ("Move Layer Down"), null, "Menu.Layers.MoveLayerDown.png");
Properties = new Gtk.Action ("Properties", Catalog.GetString ("Layer Properties..."), null, "Menu.Layers.LayerProperties.png");
@@ -88,7 +88,7 @@ public void CreateMainMenu (Gtk.Menu menu)
menu.AppendSeparator ();
menu.Append (FlipHorizontal.CreateMenuItem ());
menu.Append (FlipVertical.CreateMenuItem ());
- //menu.Append (RotateZoom.CreateAcceleratedMenuItem (Gdk.Key.Z, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
+ menu.Append (RotateZoom.CreateMenuItem ());
menu.AppendSeparator ();
menu.Append (Properties.CreateAcceleratedMenuItem (Gdk.Key.F4, Gdk.ModifierType.None));
}
@@ -655,37 +655,34 @@ public void ResizeImage (int width, int height)
// Rotate image 180 degrees (flip H+V)
public void RotateImage180 ()
{
- foreach (var layer in Layers)
- layer.Rotate180 ();
-
- Workspace.Invalidate ();
+ RotateImage (180);
}
public void RotateImageCW ()
{
- foreach (var layer in Layers)
- layer.Rotate90CW ();
-
- ImageSize = new Gdk.Size (ImageSize.Height, ImageSize.Width);
- Workspace.CanvasSize = new Gdk.Size (Workspace.CanvasSize.Height, Workspace.CanvasSize.Width);
-
- PintaCore.Actions.View.UpdateCanvasScale ();
-
- Workspace.Invalidate ();
+ RotateImage (90);
}
public void RotateImageCCW ()
{
+ RotateImage (-90);
+ }
+
+ /// <summary>
+ /// Rotates the image by the specified angle (in degrees)
+ /// </summary>
+ private void RotateImage (double angle)
+ {
foreach (var layer in Layers)
- layer.Rotate90CCW ();
+ {
+ layer.Rotate (angle);
+ }
- ImageSize = new Gdk.Size (ImageSize.Height, ImageSize.Width);
- Workspace.CanvasSize = new Gdk.Size (Workspace.CanvasSize.Height, Workspace.CanvasSize.Width);
+ ImageSize = Layer.RotateDimensions (ImageSize, angle);
+ Workspace.CanvasSize = Layer.RotateDimensions (Workspace.CanvasSize, angle);
PintaCore.Actions.View.UpdateCanvasScale ();
-
Workspace.Invalidate ();
-
}
// Returns true if successful, false if canceled
@@ -118,62 +118,47 @@ public void FlipVertical ()
(old as IDisposable).Dispose ();
}
- public void Rotate180 ()
- {
- Layer dest = PintaCore.Layers.CreateLayer ();
-
- using (Cairo.Context g = new Cairo.Context (dest.Surface)) {
- g.Matrix = new Matrix (-1, 0, 0, -1, Surface.Width, Surface.Height);
- g.SetSource (Surface);
-
- g.Paint ();
- }
-
- Surface old = Surface;
- Surface = dest.Surface;
- (old as IDisposable).Dispose ();
- }
-
- public void Rotate90CW ()
+ /// <summary>
+ /// Rotates layer by the specified angle (in degrees).
+ /// </summary>
+ /// <param name='angle'>
+ /// Angle (in degrees).
+ /// </param>
+ public void Rotate (double angle)
{
int w = PintaCore.Workspace.ImageSize.Width;
int h = PintaCore.Workspace.ImageSize.Height;
-
- Layer dest = PintaCore.Layers.CreateLayer (string.Empty, h, w);
-
+
+ double radians = (angle / 180d) * Math.PI;
+ double cos = Math.Cos (radians);
+ double sin = Math.Sin (radians);
+
+ var newSize = RotateDimensions (PintaCore.Workspace.ImageSize, angle);
+
+ Layer dest = PintaCore.Layers.CreateLayer (string.Empty, newSize.Width, newSize.Height);
+
using (Cairo.Context g = new Cairo.Context (dest.Surface)) {
- g.Translate (h / 2d, w / 2d);
- g.Rotate (Math.PI / 2);
- g.Translate (-w / 2d, -h / 2d);
+ g.Matrix = new Matrix (cos, sin, -sin, cos, newSize.Width / 2.0, newSize.Height / 2.0);
+ g.Translate (-w / 2.0, -h / 2.0);
g.SetSource (Surface);
-
+
g.Paint ();
}
Surface old = Surface;
Surface = dest.Surface;
(old as IDisposable).Dispose ();
}
-
- public void Rotate90CCW ()
+
+ public static Gdk.Size RotateDimensions (Gdk.Size originalSize, double angle)
{
- int w = PintaCore.Workspace.ImageSize.Width;
- int h = PintaCore.Workspace.ImageSize.Height;
-
- Layer dest = PintaCore.Layers.CreateLayer (string.Empty, h, w);
-
- using (Cairo.Context g = new Cairo.Context (dest.Surface)) {
- g.Translate (h / 2, w / 2);
- g.Rotate (Math.PI / -2);
- g.Translate (-w / 2, -h / 2);
- g.SetSource (Surface);
-
- g.Paint ();
- }
-
- Surface old = Surface;
- Surface = dest.Surface;
- (old as IDisposable).Dispose ();
+ double radians = (angle / 180d) * Math.PI;
+ double cos = Math.Abs (Math.Cos (radians));
+ double sin = Math.Abs (Math.Sin (radians));
+ int w = originalSize.Width;
+ int h = originalSize.Height;
+
+ return new Gdk.Size ((int)(w * cos + h * sin), (int)(w * sin + h * cos));
}
public unsafe void HueSaturation (int hueDelta, int satDelta, int lightness)
@@ -0,0 +1,90 @@
+//
+// RotateZoomLayerAction.cs
+//
+// Author:
+// Cameron White <cameronwhite91@gmail.com>
+//
+// Copyright (c) 2012 Cameron White
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using Pinta.Core;
+using Pinta.Gui.Widgets;
+using Mono.Unix;
+
+namespace Pinta.Actions
+{
+ public class RotateZoomLayerAction : IActionHandler
+ {
+ public void Initialize ()
+ {
+ PintaCore.Actions.Layers.RotateZoom.Activated += Activated;
+ }
+
+ public void Uninitialize ()
+ {
+ PintaCore.Actions.Layers.RotateZoom.Activated -= Activated;
+ }
+
+ private void Activated (object sender, EventArgs e)
+ {
+ // TODO - allow the layer to be zoomed in or out
+ // TODO - show a live preview of the rotation
+
+ var rotateZoomData = new RotateZoomData ();
+ var dialog = new SimpleEffectDialog (Catalog.GetString ("Rotate / Zoom Layer"),
+ PintaCore.Resources.GetIcon ("Menu.Layers.RotateZoom.png"), rotateZoomData);
+
+ int response = dialog.Run ();
+
+ if (response == (int)Gtk.ResponseType.Ok && !rotateZoomData.IsDefault)
+ {
+ DoRotate (rotateZoomData);
+ }
+
+ dialog.Destroy ();
+ }
+
+ private void DoRotate (RotateZoomData rotateZoomData)
+ {
+ Document doc = PintaCore.Workspace.ActiveDocument;
+ PintaCore.Tools.Commit ();
+
+ var oldSurface = doc.CurrentLayer.Surface.Clone ();
+
+ doc.CurrentLayer.Rotate (rotateZoomData.Angle);
+ doc.Workspace.Invalidate ();
+
+ var historyItem = new SimpleHistoryItem ("Menu.Layers.RotateZoom.png", Catalog.GetString ("Rotate / Zoom Layer"), oldSurface, doc.CurrentLayerIndex);
+
+ doc.History.PushNewItem (historyItem);
+ }
+
+ private class RotateZoomData : EffectData
+ {
+ public double Angle = 0;
+
+ public override bool IsDefault {
+ get { return Angle == 0; }
+ }
+ }
+ }
+}
+
@@ -60,6 +60,7 @@ public ActionHandlers ()
// Layers
action_handlers.Add (new LayerPropertiesAction ());
+ action_handlers.Add (new RotateZoomLayerAction ());
// View
action_handlers.Add (new ToolBarToggledAction ());
View
@@ -120,6 +120,7 @@
<Compile Include="Actions\Image\ResizeCanvasAction.cs" />
<Compile Include="Actions\Image\ResizeImageAction.cs" />
<Compile Include="Actions\Layers\LayerPropertiesAction.cs" />
+ <Compile Include="Actions\Layers\RotateZoomLayerAction.cs" />
<Compile Include="Actions\View\ToolBarToggledAction.cs" />
<Compile Include="Actions\Window\CloseAllDocumentsAction.cs" />
<Compile Include="Actions\Window\SaveAllDocumentsAction.cs" />
@@ -209,4 +210,4 @@
<Content Include="Pinta.ico" />
</ItemGroup>
<ItemGroup />
-</Project>
+</Project>
View
@@ -1184,8 +1184,8 @@ msgstr ""
msgid "Flip Vertical"
msgstr ""
-#: Pinta.Core/Actions/LayerActions.cs:71
-msgid "Rotate / Zoom"
+#: Pinta.Core/Actions/LayerActions.cs:72
+msgid "Rotate / Zoom Layer..."
msgstr ""
#: Pinta.Core/Actions/LayerActions.cs:72
@@ -1618,3 +1618,8 @@ msgstr ""
#: Pinta.Core/Actions/EditActions.cs:255
msgid "Don't change canvas size"
msgstr ""
+
+#: Pinta/Actions/Layers/RotateZoomLayerAction.cs:49
+#: Pinta/Actions/Layers/RotateZoomLayerAction.cs:72
+msgid "Rotate / Zoom Layer"
+msgstr ""

0 comments on commit b63054c

Please sign in to comment.