~mantas/pinta/stable

« back to all changes in this revision

Viewing changes to Pinta.Core/Actions/EditActions.cs

  • Committer: Iain Lane
  • Date: 2010-02-19 15:33:30 UTC
  • Revision ID: git-v1:92cc09614a4e2801bfe39cd971f6b31e694a500b
ImportedĀ UpstreamĀ versionĀ 0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 
 
2
// EditActions.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 Gtk;
 
29
using Cairo;
 
30
 
 
31
namespace Pinta.Core
 
32
{
 
33
        public class EditActions
 
34
        {
 
35
                public Gtk.Action Undo { get; private set; }
 
36
                public Gtk.Action Redo { get; private set; }
 
37
                public Gtk.Action Cut { get; private set; }
 
38
                public Gtk.Action Copy { get; private set; }
 
39
                public Gtk.Action Paste { get; private set; }
 
40
                public Gtk.Action PasteIntoNewLayer { get; private set; }
 
41
                public Gtk.Action PasteIntoNewImage { get; private set; }
 
42
                public Gtk.Action EraseSelection { get; private set; }
 
43
                public Gtk.Action FillSelection { get; private set; }
 
44
                public Gtk.Action InvertSelection { get; private set; }
 
45
                public Gtk.Action SelectAll { get; private set; }
 
46
                public Gtk.Action Deselect { get; private set; }
 
47
                
 
48
                public EditActions ()
 
49
                {
 
50
                        Gtk.IconFactory fact = new Gtk.IconFactory ();
 
51
                        fact.Add ("Menu.Edit.Deselect.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.Deselect.png")));
 
52
                        fact.Add ("Menu.Edit.EraseSelection.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.EraseSelection.png")));
 
53
                        fact.Add ("Menu.Edit.FillSelection.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.FillSelection.png")));
 
54
                        fact.Add ("Menu.Edit.InvertSelection.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.InvertSelection.png")));
 
55
                        fact.Add ("Menu.Edit.SelectAll.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.SelectAll.png")));
 
56
                        fact.AddDefault ();
 
57
                        
 
58
                        Undo = new Gtk.Action ("Undo", Mono.Unix.Catalog.GetString ("Undo"), null, "gtk-undo");
 
59
                        Redo = new Gtk.Action ("Redo", Mono.Unix.Catalog.GetString ("Redo"), null, "gtk-redo");
 
60
                        Cut = new Gtk.Action ("Cut", Mono.Unix.Catalog.GetString ("Cut"), null, "gtk-cut");
 
61
                        Copy = new Gtk.Action ("Copy", Mono.Unix.Catalog.GetString ("Copy"), null, "gtk-copy");
 
62
                        Paste = new Gtk.Action ("Paste", Mono.Unix.Catalog.GetString ("Paste"), null, "gtk-paste");
 
63
                        PasteIntoNewLayer = new Gtk.Action ("PasteIntoNewLayer", Mono.Unix.Catalog.GetString ("Paste Into New Layer"), null, "gtk-paste");
 
64
                        PasteIntoNewImage = new Gtk.Action ("PasteIntoNewImage", Mono.Unix.Catalog.GetString ("Paste Into New Image"), null, "gtk-paste");
 
65
                        EraseSelection = new Gtk.Action ("EraseSelection", Mono.Unix.Catalog.GetString ("Erase Selection"), null, "Menu.Edit.EraseSelection.png");
 
66
                        FillSelection = new Gtk.Action ("FillSelection", Mono.Unix.Catalog.GetString ("Fill Selection"), null, "Menu.Edit.FillSelection.png");
 
67
                        InvertSelection = new Gtk.Action ("InvertSelection", Mono.Unix.Catalog.GetString ("Invert Selection"), null, "Menu.Edit.InvertSelection.png");
 
68
                        SelectAll = new Gtk.Action ("SelectAll", Mono.Unix.Catalog.GetString ("Select All"), null, "Menu.Edit.SelectAll.png");
 
69
                        Deselect = new Gtk.Action ("Deselect", Mono.Unix.Catalog.GetString ("Deselect"), null, "Menu.Edit.Deselect.png");
 
70
                        
 
71
                        Undo.Sensitive = false;
 
72
                        Redo.Sensitive = false;
 
73
                        PasteIntoNewImage.Sensitive = false;
 
74
                        InvertSelection.Sensitive = false;
 
75
                        Deselect.Sensitive = false;
 
76
                }
 
77
 
 
78
                #region Initialization
 
79
                public void CreateMainMenu (Gtk.Menu menu)
 
80
                {
 
81
                        menu.Remove (menu.Children[1]);
 
82
                        
 
83
                        menu.Append (Undo.CreateAcceleratedMenuItem (Gdk.Key.Z, Gdk.ModifierType.ControlMask));
 
84
                        menu.Append (Redo.CreateAcceleratedMenuItem (Gdk.Key.Y, Gdk.ModifierType.ControlMask));
 
85
                        menu.AppendSeparator ();
 
86
                        menu.Append (Cut.CreateAcceleratedMenuItem (Gdk.Key.X, Gdk.ModifierType.ControlMask));
 
87
                        menu.Append (Copy.CreateAcceleratedMenuItem (Gdk.Key.C, Gdk.ModifierType.ControlMask));
 
88
                        menu.Append (Paste.CreateAcceleratedMenuItem (Gdk.Key.V, Gdk.ModifierType.ControlMask));
 
89
                        menu.Append (PasteIntoNewLayer.CreateAcceleratedMenuItem (Gdk.Key.V, Gdk.ModifierType.ShiftMask));
 
90
                        //menu.Append (PasteIntoNewImage.CreateAcceleratedMenuItem (Gdk.Key.V, Gdk.ModifierType.Mod1Mask));
 
91
                        menu.AppendSeparator ();
 
92
                        menu.Append (EraseSelection.CreateAcceleratedMenuItem (Gdk.Key.Delete, Gdk.ModifierType.None));
 
93
                        menu.Append (FillSelection.CreateAcceleratedMenuItem (Gdk.Key.BackSpace, Gdk.ModifierType.None));
 
94
                        //menu.Append (InvertSelection.CreateAcceleratedMenuItem (Gdk.Key.I, Gdk.ModifierType.ControlMask));
 
95
                        menu.Append (SelectAll.CreateAcceleratedMenuItem (Gdk.Key.A, Gdk.ModifierType.ControlMask));
 
96
                        menu.Append (Deselect.CreateAcceleratedMenuItem (Gdk.Key.D, Gdk.ModifierType.ControlMask));
 
97
                }
 
98
 
 
99
                public void CreateHistoryWindowToolBar (Gtk.Toolbar toolbar)
 
100
                {
 
101
                        toolbar.AppendItem (Undo.CreateToolBarItem ());
 
102
                        toolbar.AppendItem (Redo.CreateToolBarItem ());
 
103
                }
 
104
 
 
105
                public void RegisterHandlers ()
 
106
                {
 
107
                        Deselect.Activated += HandlePintaCoreActionsEditDeselectActivated;
 
108
                        EraseSelection.Activated += HandlePintaCoreActionsEditEraseSelectionActivated;
 
109
                        SelectAll.Activated += HandlePintaCoreActionsEditSelectAllActivated;
 
110
                        FillSelection.Activated += HandlePintaCoreActionsEditFillSelectionActivated;
 
111
                        PasteIntoNewLayer.Activated += HandlerPintaCoreActionsEditPasteIntoNewLayerActivated;
 
112
                        Paste.Activated += HandlerPintaCoreActionsEditPasteActivated;
 
113
                        Copy.Activated += HandlerPintaCoreActionsEditCopyActivated;
 
114
                        Undo.Activated += HandlerPintaCoreActionsEditUndoActivated;
 
115
                        Redo.Activated += HandlerPintaCoreActionsEditRedoActivated;
 
116
                        Cut.Activated += HandlerPintaCoreActionsEditCutActivated;
 
117
                }
 
118
                #endregion
 
119
 
 
120
                #region Action Handlers
 
121
                private void HandlePintaCoreActionsEditFillSelectionActivated (object sender, EventArgs e)
 
122
                {
 
123
                        PintaCore.Layers.FinishSelection ();
 
124
                        
 
125
                        Cairo.ImageSurface old = PintaCore.Layers.CurrentLayer.Surface.Clone ();
 
126
                        
 
127
                        using (Cairo.Context g = new Cairo.Context (PintaCore.Layers.CurrentLayer.Surface)) {
 
128
                                g.AppendPath (PintaCore.Layers.SelectionPath);
 
129
                                g.FillRule = Cairo.FillRule.EvenOdd;
 
130
                                g.Color = PintaCore.Palette.PrimaryColor;
 
131
                                g.Fill ();
 
132
                        }
 
133
                        
 
134
                        PintaCore.Workspace.Invalidate ();
 
135
                        PintaCore.History.PushNewItem (new SimpleHistoryItem ("Menu.Edit.FillSelection.png", Mono.Unix.Catalog.GetString ("Fill Selection"), old, PintaCore.Layers.CurrentLayerIndex));
 
136
                }
 
137
 
 
138
                private void HandlePintaCoreActionsEditSelectAllActivated (object sender, EventArgs e)
 
139
                {
 
140
                        PintaCore.Layers.FinishSelection ();
 
141
 
 
142
                        SelectionHistoryItem hist = new SelectionHistoryItem ("Menu.Edit.SelectAll.png", Mono.Unix.Catalog.GetString ("Select All"));
 
143
                        hist.TakeSnapshot ();
 
144
 
 
145
                        PintaCore.Layers.ResetSelectionPath ();
 
146
                        PintaCore.Layers.ShowSelection = true;
 
147
 
 
148
                        PintaCore.History.PushNewItem (hist);
 
149
                        PintaCore.Workspace.Invalidate ();
 
150
                }
 
151
 
 
152
                private void HandlePintaCoreActionsEditEraseSelectionActivated (object sender, EventArgs e)
 
153
                {
 
154
                        PintaCore.Layers.FinishSelection ();
 
155
 
 
156
                        Cairo.ImageSurface old = PintaCore.Layers.CurrentLayer.Surface.Clone ();
 
157
 
 
158
                        using (Cairo.Context g = new Cairo.Context (PintaCore.Layers.CurrentLayer.Surface)) {
 
159
                                g.AppendPath (PintaCore.Layers.SelectionPath);
 
160
                                g.FillRule = Cairo.FillRule.EvenOdd;
 
161
                                g.Operator = Cairo.Operator.Clear;
 
162
                                g.Fill ();
 
163
                        }
 
164
                        
 
165
                        PintaCore.Workspace.Invalidate ();
 
166
                        PintaCore.History.PushNewItem (new SimpleHistoryItem ("Menu.Edit.EraseSelection.png", Mono.Unix.Catalog.GetString ("Erase Selection"), old, PintaCore.Layers.CurrentLayerIndex));
 
167
                }
 
168
 
 
169
                private void HandlePintaCoreActionsEditDeselectActivated (object sender, EventArgs e)
 
170
                {
 
171
                        PintaCore.Layers.FinishSelection ();
 
172
 
 
173
                        SelectionHistoryItem hist = new SelectionHistoryItem ("Menu.Edit.Deselect.png", Mono.Unix.Catalog.GetString ("Deselect"));
 
174
                        hist.TakeSnapshot ();
 
175
                        
 
176
                        PintaCore.Layers.ResetSelectionPath ();
 
177
                        
 
178
                        PintaCore.History.PushNewItem (hist);
 
179
                        PintaCore.Workspace.Invalidate ();
 
180
                }
 
181
 
 
182
                private void HandlerPintaCoreActionsEditPasteIntoNewLayerActivated (object sender, EventArgs e)
 
183
                {
 
184
                        PintaCore.Layers.FinishSelection ();
 
185
 
 
186
                        Gtk.Clipboard cb = Gtk.Clipboard.Get (Gdk.Atom.Intern ("CLIPBOARD", false));
 
187
                        Gdk.Pixbuf image = cb.WaitForImage ();
 
188
 
 
189
                        // TODO: Message window saying no image on clipboard
 
190
                        if (image == null)
 
191
                                return;
 
192
 
 
193
                        Layer l = PintaCore.Layers.AddNewLayer (string.Empty);
 
194
 
 
195
                        using (Cairo.Context g = new Cairo.Context (l.Surface))
 
196
                                g.DrawPixbuf (image, new Cairo.Point (0, 0));
 
197
 
 
198
                        // Make new layer the current layer
 
199
                        PintaCore.Layers.SetCurrentLayer (l);
 
200
                        
 
201
                        PintaCore.Workspace.Invalidate ();
 
202
 
 
203
                        // TODO: Need paste icon
 
204
                        AddLayerHistoryItem hist = new AddLayerHistoryItem ("Menu.Edit.EraseSelection.png", Mono.Unix.Catalog.GetString ("Paste Into New Layer"), PintaCore.Layers.IndexOf (l));
 
205
                        PintaCore.History.PushNewItem (hist);
 
206
                }
 
207
 
 
208
                private void HandlerPintaCoreActionsEditPasteActivated (object sender, EventArgs e)
 
209
                {
 
210
                        PintaCore.Layers.FinishSelection ();
 
211
 
 
212
                        Cairo.ImageSurface old = PintaCore.Layers.CurrentLayer.Surface.Clone ();
 
213
 
 
214
                        Gtk.Clipboard cb = Gtk.Clipboard.Get (Gdk.Atom.Intern ("CLIPBOARD", false));
 
215
                        Gdk.Pixbuf image = cb.WaitForImage ();
 
216
 
 
217
                        if (image == null)
 
218
                                return;
 
219
 
 
220
                        Path p;
 
221
                        
 
222
                        using (Cairo.Context g = new Cairo.Context (PintaCore.Layers.CurrentLayer.Surface)) {
 
223
                                g.DrawPixbuf (image, new Cairo.Point (0, 0));
 
224
                                p = g.CreateRectanglePath (new Rectangle (0, 0, image.Width, image.Height));
 
225
                        }
 
226
 
 
227
                        PintaCore.Layers.SelectionPath = p;
 
228
                        PintaCore.Layers.ShowSelection = true;
 
229
                        
 
230
                        PintaCore.Workspace.Invalidate ();
 
231
                        
 
232
                        // TODO: Need paste icon
 
233
                        PintaCore.History.PushNewItem (new SimpleHistoryItem ("Menu.Edit.EraseSelection.png", Mono.Unix.Catalog.GetString ("Paste"), old, PintaCore.Layers.CurrentLayerIndex));
 
234
                }
 
235
 
 
236
                private void HandlerPintaCoreActionsEditCopyActivated (object sender, EventArgs e)
 
237
                {
 
238
                        PintaCore.Layers.FinishSelection ();
 
239
 
 
240
                        ImageSurface src = PintaCore.Layers.GetClippedLayer (PintaCore.Layers.CurrentLayerIndex);
 
241
                        
 
242
                        Cairo.Rectangle rect = PintaCore.Layers.SelectionPath.GetBounds ();
 
243
                        
 
244
                        ImageSurface dest = new ImageSurface (Format.Argb32, (int)rect.Width, (int)rect.Height);
 
245
 
 
246
                        using (Context g = new Context (dest)) {
 
247
                                g.SetSourceSurface (src, -(int)rect.X, -(int)rect.Y);
 
248
                                g.Paint ();
 
249
                        }
 
250
                        
 
251
                        Gtk.Clipboard cb = Gtk.Clipboard.Get (Gdk.Atom.Intern ("CLIPBOARD", false));
 
252
                        cb.Image = dest.ToPixbuf ();
 
253
 
 
254
                        (src as IDisposable).Dispose ();
 
255
                        (dest as IDisposable).Dispose ();
 
256
                }
 
257
                
 
258
                private void HandlerPintaCoreActionsEditCutActivated (object sender, EventArgs e)
 
259
                {
 
260
                        PintaCore.Layers.FinishSelection ();
 
261
                        
 
262
                        // Copy selection
 
263
                        HandlerPintaCoreActionsEditCopyActivated (sender, e);
 
264
 
 
265
                        // Erase selection
 
266
                        Cairo.ImageSurface old = PintaCore.Layers.CurrentLayer.Surface.Clone ();
 
267
 
 
268
                        using (Cairo.Context g = new Cairo.Context (PintaCore.Layers.CurrentLayer.Surface)) {
 
269
                                g.AppendPath (PintaCore.Layers.SelectionPath);
 
270
                                g.FillRule = Cairo.FillRule.EvenOdd;
 
271
                                g.Operator = Cairo.Operator.Clear;
 
272
                                g.Fill ();
 
273
                        }
 
274
 
 
275
                        PintaCore.Workspace.Invalidate ();
 
276
                        PintaCore.History.PushNewItem (new SimpleHistoryItem ("Menu.Edit.EraseSelection.png", Mono.Unix.Catalog.GetString ("Cut"), old, PintaCore.Layers.CurrentLayerIndex));
 
277
                }
 
278
 
 
279
                private void HandlerPintaCoreActionsEditUndoActivated (object sender, EventArgs e)
 
280
                {
 
281
                        PintaCore.History.Undo ();
 
282
                }
 
283
 
 
284
                private void HandlerPintaCoreActionsEditRedoActivated (object sender, EventArgs e)
 
285
                {
 
286
                        PintaCore.History.Redo ();
 
287
                }
 
288
                #endregion
 
289
        }
 
290
}