1 // 2 // LayerActions.cs 3 // 4 // Author: 5 // Jonathan Pobst <monkey@jpobst.com> 6 // 7 // Copyright (c) 2010 Jonathan Pobst 8 // 9 // Permission is hereby granted, free of charge, to any person obtaining a copy 10 // of this software and associated documentation files (the "Software"), to deal 11 // in the Software without restriction, including without limitation the rights 12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 // copies of the Software, and to permit persons to whom the Software is 14 // furnished to do so, subject to the following conditions: 15 // 16 // The above copyright notice and this permission notice shall be included in 17 // all copies or substantial portions of the Software. 18 // 19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 // THE SOFTWARE. 26 27 using System; 28 using Gdk; 29 using Gtk; 30 using Mono.Unix; 31 using System.IO; 32 33 namespace Pinta.Core 34 { 35 public class LayerActions 36 { 37 public Gtk.Action AddNewLayer { get; private set; } 38 public Gtk.Action DeleteLayer { get; private set; } 39 public Gtk.Action DuplicateLayer { get; private set; } 40 public Gtk.Action MergeLayerDown { get; private set; } 41 public Gtk.Action ImportFromFile { get; private set; } 42 public Gtk.Action FlipHorizontal { get; private set; } 43 public Gtk.Action FlipVertical { get; private set; } 44 public Gtk.Action RotateZoom { get; private set; } 45 public Gtk.Action MoveLayerUp { get; private set; } 46 public Gtk.Action MoveLayerDown { get; private set; } 47 public Gtk.Action Properties { get; private set; } 48 LayerActions()49 public LayerActions () 50 { 51 Gtk.IconFactory fact = new Gtk.IconFactory (); 52 fact.Add ("Menu.Layers.AddNewLayer.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.AddNewLayer.png"))); 53 fact.Add ("Menu.Layers.DeleteLayer.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.DeleteLayer.png"))); 54 fact.Add ("Menu.Layers.DuplicateLayer.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.DuplicateLayer.png"))); 55 fact.Add ("Menu.Layers.MergeLayerDown.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.MergeLayerDown.png"))); 56 fact.Add ("Menu.Layers.MoveLayerDown.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.MoveLayerDown.png"))); 57 fact.Add ("Menu.Layers.MoveLayerUp.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.MoveLayerUp.png"))); 58 fact.Add ("Menu.Layers.FlipHorizontal.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.FlipHorizontal.png"))); 59 fact.Add ("Menu.Layers.FlipVertical.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.FlipVertical.png"))); 60 fact.Add ("Menu.Layers.ImportFromFile.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.ImportFromFile.png"))); 61 fact.Add ("Menu.Layers.LayerProperties.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.LayerProperties.png"))); 62 fact.Add ("Menu.Layers.RotateZoom.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.RotateZoom.png"))); 63 fact.AddDefault (); 64 65 AddNewLayer = new Gtk.Action ("AddNewLayer", Catalog.GetString ("Add New Layer"), null, "Menu.Layers.AddNewLayer.png"); 66 DeleteLayer = new Gtk.Action ("DeleteLayer", Catalog.GetString ("Delete Layer"), null, "Menu.Layers.DeleteLayer.png"); 67 DuplicateLayer = new Gtk.Action ("DuplicateLayer", Catalog.GetString ("Duplicate Layer"), null, "Menu.Layers.DuplicateLayer.png"); 68 MergeLayerDown = new Gtk.Action ("MergeLayerDown", Catalog.GetString ("Merge Layer Down"), null, "Menu.Layers.MergeLayerDown.png"); 69 ImportFromFile = new Gtk.Action ("ImportFromFile", Catalog.GetString ("Import from File..."), null, "Menu.Layers.ImportFromFile.png"); 70 FlipHorizontal = new Gtk.Action ("FlipHorizontal", Catalog.GetString ("Flip Horizontal"), null, "Menu.Layers.FlipHorizontal.png"); 71 FlipVertical = new Gtk.Action ("FlipVertical", Catalog.GetString ("Flip Vertical"), null, "Menu.Layers.FlipVertical.png"); 72 RotateZoom = new Gtk.Action ("RotateZoom", Catalog.GetString ("Rotate / Zoom Layer..."), null, "Menu.Layers.RotateZoom.png"); 73 MoveLayerUp = new Gtk.Action ("MoveLayerUp", Catalog.GetString ("Move Layer Up"), null, "Menu.Layers.MoveLayerUp.png"); 74 MoveLayerDown = new Gtk.Action ("MoveLayerDown", Catalog.GetString ("Move Layer Down"), null, "Menu.Layers.MoveLayerDown.png"); 75 Properties = new Gtk.Action ("Properties", Catalog.GetString ("Layer Properties..."), null, "Menu.Layers.LayerProperties.png"); 76 77 RotateZoom.Sensitive = false; 78 } 79 80 #region Initialization CreateMainMenu(Gtk.Menu menu)81 public void CreateMainMenu (Gtk.Menu menu) 82 { 83 menu.Append (AddNewLayer.CreateAcceleratedMenuItem (Gdk.Key.N, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask)); 84 menu.Append (DeleteLayer.CreateAcceleratedMenuItem (Gdk.Key.Delete, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask)); 85 menu.Append (DuplicateLayer.CreateAcceleratedMenuItem (Gdk.Key.D, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask)); 86 menu.Append (MergeLayerDown.CreateAcceleratedMenuItem (Gdk.Key.M, Gdk.ModifierType.ControlMask)); 87 menu.Append (ImportFromFile.CreateMenuItem ()); 88 menu.AppendSeparator (); 89 menu.Append (FlipHorizontal.CreateMenuItem ()); 90 menu.Append (FlipVertical.CreateMenuItem ()); 91 menu.Append (RotateZoom.CreateMenuItem ()); 92 menu.AppendSeparator (); 93 menu.Append (Properties.CreateAcceleratedMenuItem (Gdk.Key.F4, Gdk.ModifierType.None)); 94 } 95 CreateLayerWindowToolBar(Gtk.Toolbar toolbar)96 public void CreateLayerWindowToolBar (Gtk.Toolbar toolbar) 97 { 98 toolbar.AppendItem (AddNewLayer.CreateToolBarItem ()); 99 toolbar.AppendItem (DeleteLayer.CreateToolBarItem ()); 100 toolbar.AppendItem (DuplicateLayer.CreateToolBarItem ()); 101 toolbar.AppendItem (MergeLayerDown.CreateToolBarItem ()); 102 toolbar.AppendItem (MoveLayerUp.CreateToolBarItem ()); 103 toolbar.AppendItem (MoveLayerDown.CreateToolBarItem ()); 104 toolbar.AppendItem (Properties.CreateToolBarItem ()); 105 } 106 RegisterHandlers()107 public void RegisterHandlers () 108 { 109 AddNewLayer.Activated += HandlePintaCoreActionsLayersAddNewLayerActivated; 110 DeleteLayer.Activated += HandlePintaCoreActionsLayersDeleteLayerActivated; 111 DuplicateLayer.Activated += HandlePintaCoreActionsLayersDuplicateLayerActivated; 112 MergeLayerDown.Activated += HandlePintaCoreActionsLayersMergeLayerDownActivated; 113 MoveLayerDown.Activated += HandlePintaCoreActionsLayersMoveLayerDownActivated; 114 MoveLayerUp.Activated += HandlePintaCoreActionsLayersMoveLayerUpActivated; 115 FlipHorizontal.Activated += HandlePintaCoreActionsLayersFlipHorizontalActivated; 116 FlipVertical.Activated += HandlePintaCoreActionsLayersFlipVerticalActivated; 117 ImportFromFile.Activated += HandlePintaCoreActionsLayersImportFromFileActivated; 118 119 PintaCore.Layers.LayerAdded += EnableOrDisableLayerActions; 120 PintaCore.Layers.LayerRemoved += EnableOrDisableLayerActions; 121 PintaCore.Layers.SelectedLayerChanged += EnableOrDisableLayerActions; 122 123 EnableOrDisableLayerActions (null, EventArgs.Empty); 124 } 125 #endregion 126 127 #region Action Handlers EnableOrDisableLayerActions(object sender, EventArgs e)128 private void EnableOrDisableLayerActions (object sender, EventArgs e) 129 { 130 if (PintaCore.Workspace.HasOpenDocuments && PintaCore.Workspace.ActiveDocument.UserLayers.Count > 1) { 131 PintaCore.Actions.Layers.DeleteLayer.Sensitive = true; 132 PintaCore.Actions.Image.Flatten.Sensitive = true; 133 } else { 134 PintaCore.Actions.Layers.DeleteLayer.Sensitive = false; 135 PintaCore.Actions.Image.Flatten.Sensitive = false; 136 } 137 138 if (PintaCore.Workspace.HasOpenDocuments && PintaCore.Workspace.ActiveDocument.CurrentUserLayerIndex > 0) { 139 PintaCore.Actions.Layers.MergeLayerDown.Sensitive = true; 140 PintaCore.Actions.Layers.MoveLayerDown.Sensitive = true; 141 } else { 142 PintaCore.Actions.Layers.MergeLayerDown.Sensitive = false; 143 PintaCore.Actions.Layers.MoveLayerDown.Sensitive = false; 144 } 145 146 if (PintaCore.Workspace.HasOpenDocuments && PintaCore.Workspace.ActiveDocument.CurrentUserLayerIndex < PintaCore.Workspace.ActiveDocument.UserLayers.Count - 1) 147 PintaCore.Actions.Layers.MoveLayerUp.Sensitive = true; 148 else 149 PintaCore.Actions.Layers.MoveLayerUp.Sensitive = false; 150 } 151 HandlePintaCoreActionsLayersImportFromFileActivated(object sender, EventArgs e)152 private void HandlePintaCoreActionsLayersImportFromFileActivated (object sender, EventArgs e) 153 { 154 Document doc = PintaCore.Workspace.ActiveDocument; 155 PintaCore.Tools.Commit (); 156 157 var fcd = new Gtk.FileChooserDialog (Catalog.GetString ("Open Image File"),PintaCore.Chrome.MainWindow, 158 FileChooserAction.Open, Stock.Cancel, ResponseType.Cancel, 159 Stock.Open, ResponseType.Ok); 160 161 fcd.SetCurrentFolder (PintaCore.System.GetDialogDirectory ()); 162 fcd.AlternativeButtonOrder = new int[] { (int) ResponseType.Ok, (int) ResponseType.Cancel }; 163 164 fcd.AddImagePreview (); 165 166 int response = fcd.Run (); 167 168 if (response == (int)Gtk.ResponseType.Ok) { 169 170 string file = fcd.Filename; 171 PintaCore.System.LastDialogDirectory = fcd.CurrentFolder; 172 173 // Open the image and add it to the layers 174 UserLayer layer = doc.AddNewLayer(System.IO.Path.GetFileName(file)); 175 176 using (var fs = new FileStream (file, FileMode.Open)) 177 using (Pixbuf bg = new Pixbuf (fs)) 178 using (Cairo.Context g = new Cairo.Context (layer.Surface)) { 179 CairoHelper.SetSourcePixbuf (g, bg, 0, 0); 180 g.Paint (); 181 } 182 183 doc.SetCurrentUserLayer (layer); 184 185 AddLayerHistoryItem hist = new AddLayerHistoryItem ("Menu.Layers.ImportFromFile.png", Catalog.GetString ("Import From File"), doc.UserLayers.IndexOf (layer)); 186 doc.History.PushNewItem (hist); 187 188 doc.Workspace.Invalidate (); 189 } 190 191 fcd.Destroy (); 192 } 193 HandlePintaCoreActionsLayersFlipVerticalActivated(object sender, EventArgs e)194 private void HandlePintaCoreActionsLayersFlipVerticalActivated (object sender, EventArgs e) 195 { 196 Document doc = PintaCore.Workspace.ActiveDocument; 197 PintaCore.Tools.Commit (); 198 199 doc.CurrentUserLayer.FlipVertical (); 200 doc.Workspace.Invalidate (); 201 doc.History.PushNewItem (new InvertHistoryItem (InvertType.FlipLayerVertical, doc.CurrentUserLayerIndex)); 202 } 203 HandlePintaCoreActionsLayersFlipHorizontalActivated(object sender, EventArgs e)204 private void HandlePintaCoreActionsLayersFlipHorizontalActivated (object sender, EventArgs e) 205 { 206 Document doc = PintaCore.Workspace.ActiveDocument; 207 PintaCore.Tools.Commit (); 208 209 doc.CurrentUserLayer.FlipHorizontal (); 210 doc.Workspace.Invalidate (); 211 doc.History.PushNewItem (new InvertHistoryItem (InvertType.FlipLayerHorizontal, doc.CurrentUserLayerIndex)); 212 } 213 HandlePintaCoreActionsLayersMoveLayerUpActivated(object sender, EventArgs e)214 private void HandlePintaCoreActionsLayersMoveLayerUpActivated (object sender, EventArgs e) 215 { 216 Document doc = PintaCore.Workspace.ActiveDocument; 217 PintaCore.Tools.Commit (); 218 219 SwapLayersHistoryItem hist = new SwapLayersHistoryItem ("Menu.Layers.MoveLayerUp.png", Catalog.GetString ("Move Layer Up"), doc.CurrentUserLayerIndex, doc.CurrentUserLayerIndex + 1); 220 221 doc.MoveCurrentLayerUp (); 222 doc.History.PushNewItem (hist); 223 } 224 HandlePintaCoreActionsLayersMoveLayerDownActivated(object sender, EventArgs e)225 private void HandlePintaCoreActionsLayersMoveLayerDownActivated (object sender, EventArgs e) 226 { 227 Document doc = PintaCore.Workspace.ActiveDocument; 228 PintaCore.Tools.Commit (); 229 230 SwapLayersHistoryItem hist = new SwapLayersHistoryItem ("Menu.Layers.MoveLayerDown.png", Catalog.GetString ("Move Layer Down"), doc.CurrentUserLayerIndex, doc.CurrentUserLayerIndex - 1); 231 232 doc.MoveCurrentLayerDown (); 233 doc.History.PushNewItem (hist); 234 } 235 HandlePintaCoreActionsLayersMergeLayerDownActivated(object sender, EventArgs e)236 private void HandlePintaCoreActionsLayersMergeLayerDownActivated (object sender, EventArgs e) 237 { 238 Document doc = PintaCore.Workspace.ActiveDocument; 239 PintaCore.Tools.Commit (); 240 241 int bottomLayerIndex = doc.CurrentUserLayerIndex - 1; 242 var oldBottomSurface = doc.UserLayers[bottomLayerIndex].Surface.Clone (); 243 244 CompoundHistoryItem hist = new CompoundHistoryItem ("Menu.Layers.MergeLayerDown.png", Catalog.GetString ("Merge Layer Down")); 245 DeleteLayerHistoryItem h1 = new DeleteLayerHistoryItem (string.Empty, string.Empty, doc.CurrentUserLayer, doc.CurrentUserLayerIndex); 246 247 doc.MergeCurrentLayerDown (); 248 249 SimpleHistoryItem h2 = new SimpleHistoryItem (string.Empty, string.Empty, oldBottomSurface, bottomLayerIndex); 250 hist.Push (h1); 251 hist.Push (h2); 252 253 doc.History.PushNewItem (hist); 254 } 255 HandlePintaCoreActionsLayersDuplicateLayerActivated(object sender, EventArgs e)256 private void HandlePintaCoreActionsLayersDuplicateLayerActivated (object sender, EventArgs e) 257 { 258 Document doc = PintaCore.Workspace.ActiveDocument; 259 PintaCore.Tools.Commit (); 260 261 UserLayer l = doc.DuplicateCurrentLayer(); 262 263 // Make new layer the current layer 264 doc.SetCurrentUserLayer (l); 265 266 AddLayerHistoryItem hist = new AddLayerHistoryItem ("Menu.Layers.DuplicateLayer.png", Catalog.GetString ("Duplicate Layer"), doc.UserLayers.IndexOf (l)); 267 doc.History.PushNewItem (hist); 268 } 269 HandlePintaCoreActionsLayersDeleteLayerActivated(object sender, EventArgs e)270 private void HandlePintaCoreActionsLayersDeleteLayerActivated (object sender, EventArgs e) 271 { 272 Document doc = PintaCore.Workspace.ActiveDocument; 273 PintaCore.Tools.Commit (); 274 275 DeleteLayerHistoryItem hist = new DeleteLayerHistoryItem ("Menu.Layers.DeleteLayer.png", Catalog.GetString ("Delete Layer"), doc.CurrentUserLayer, doc.CurrentUserLayerIndex); 276 277 doc.DeleteLayer (doc.CurrentUserLayerIndex, false); 278 279 doc.History.PushNewItem (hist); 280 } 281 HandlePintaCoreActionsLayersAddNewLayerActivated(object sender, EventArgs e)282 private void HandlePintaCoreActionsLayersAddNewLayerActivated (object sender, EventArgs e) 283 { 284 Document doc = PintaCore.Workspace.ActiveDocument; 285 PintaCore.Tools.Commit (); 286 287 UserLayer l = doc.AddNewLayer(string.Empty); 288 289 // Make new layer the current layer 290 doc.SetCurrentUserLayer (l); 291 292 AddLayerHistoryItem hist = new AddLayerHistoryItem ("Menu.Layers.AddNewLayer.png", Catalog.GetString ("Add New Layer"), doc.UserLayers.IndexOf (l)); 293 doc.History.PushNewItem (hist); 294 } 295 #endregion 296 } 297 } 298