private void Activated(object sender, EventArgs e) { Gtk.Clipboard cb = Gtk.Clipboard.Get (Gdk.Atom.Intern ("CLIPBOARD", false)); if (cb.WaitIsImageAvailable ()) { PintaCore.Tools.Commit (); Gdk.Pixbuf image = cb.WaitForImage (); Layer l = PintaCore.Layers.AddNewLayer (string.Empty); using (Cairo.Context g = new Cairo.Context (l.Surface)) g.DrawPixbuf (image, new Cairo.Point (0, 0)); // Make new layer the current layer PintaCore.Layers.SetCurrentLayer (l); PintaCore.Workspace.Invalidate (); AddLayerHistoryItem hist = new AddLayerHistoryItem (Stock.Paste, Catalog.GetString ("Paste Into New Layer"), PintaCore.Layers.IndexOf (l)); PintaCore.History.PushNewItem (hist); } else { ClipboardEmptyError (); } }
private void Activated(object sender, EventArgs e) { Gtk.Clipboard cb = Gtk.Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false)); if (cb.WaitIsImageAvailable()) { PintaCore.Tools.Commit(); Gdk.Pixbuf image = cb.WaitForImage(); Layer l = PintaCore.Layers.AddNewLayer(string.Empty); using (Cairo.Context g = new Cairo.Context(l.Surface)) g.DrawPixbuf(image, new Cairo.Point(0, 0)); // Make new layer the current layer PintaCore.Layers.SetCurrentLayer(l); PintaCore.Workspace.Invalidate(); AddLayerHistoryItem hist = new AddLayerHistoryItem(Stock.Paste, Catalog.GetString("Paste Into New Layer"), PintaCore.Layers.IndexOf(l)); PintaCore.History.PushNewItem(hist); } else { Pinta.Dialogs.ClipboardEmptyDialog.Show(); } }
/// <summary> /// Create a cursor icon with a shape that visually represents the tool's thickness. /// </summary> /// <param name="imgName">A string containing the name of the tool's icon image to use.</param> /// <param name="shape">The shape to draw.</param> /// <param name="shapeWidth">The width of the shape.</param> /// <param name="imgToShapeX">The horizontal distance between the image's top-left corner and the shape center.</param> /// <param name="imgToShapeY">The verical distance between the image's top-left corner and the shape center.</param> /// <param name="shapeX">The X position in the returned Pixbuf that will be the center of the shape.</param> /// <param name="shapeY">The Y position in the returned Pixbuf that will be the center of the shape.</param> /// <returns>The new cursor icon with an shape that represents the tool's thickness.</returns> public static Gdk.Pixbuf CreateIconWithShape(string imgName, CursorShape shape, int shapeWidth, int imgToShapeX, int imgToShapeY, out int shapeX, out int shapeY) { Gdk.Pixbuf img = PintaCore.Resources.GetIcon(imgName); double zoom = 1d; if (PintaCore.Workspace.HasOpenDocuments) { zoom = Math.Min(30d, PintaCore.Workspace.ActiveDocument.Workspace.Scale); } shapeWidth = (int)Math.Min(800d, ((double)shapeWidth) * zoom); int halfOfShapeWidth = shapeWidth / 2; // Calculate bounding boxes around the both image and shape // relative to the image top-left corner. Gdk.Rectangle imgBBox = new Gdk.Rectangle(0, 0, img.Width, img.Height); Gdk.Rectangle shapeBBox = new Gdk.Rectangle( imgToShapeX - halfOfShapeWidth, imgToShapeY - halfOfShapeWidth, shapeWidth, shapeWidth); // Inflate shape bounding box to allow for anti-aliasing shapeBBox.Inflate(2, 2); // To determine required size of icon, // find union of the image and shape bounding boxes // (still relative to image top-left corner) Gdk.Rectangle iconBBox = imgBBox.Union(shapeBBox); // Image top-left corner in icon co-ordinates int imgX = imgBBox.Left - iconBBox.Left; int imgY = imgBBox.Top - iconBBox.Top; // Shape center point in icon co-ordinates shapeX = imgToShapeX - iconBBox.Left; shapeY = imgToShapeY - iconBBox.Top; using (var i = CairoExtensions.CreateImageSurface(Cairo.Format.ARGB32, iconBBox.Width, iconBBox.Height)) { using (var g = new Cairo.Context(i)) { // Don't show shape if shapeWidth less than 3, if (shapeWidth > 3) { int diam = Math.Max(1, shapeWidth - 2); Cairo.Rectangle shapeRect = new Cairo.Rectangle(shapeX - halfOfShapeWidth, shapeY - halfOfShapeWidth, diam, diam); Cairo.Color outerColor = new Cairo.Color(255, 255, 255, 0.75); Cairo.Color innerColor = new Cairo.Color(0, 0, 0); switch (shape) { case CursorShape.Ellipse: g.DrawEllipse(shapeRect, outerColor, 2); shapeRect = shapeRect.Inflate(-1, -1); g.DrawEllipse(shapeRect, innerColor, 1); break; case CursorShape.Rectangle: g.DrawRectangle(shapeRect, outerColor, 1); shapeRect = shapeRect.Inflate(-1, -1); g.DrawRectangle(shapeRect, innerColor, 1); break; } } // Draw the image g.DrawPixbuf(img, new Cairo.Point(imgX, imgY)); } return(CairoExtensions.ToPixbuf(i)); } }
/// <summary> /// Pastes an image from the clipboard. /// </summary> /// <param name="toNewLayer">Set to TRUE to paste into a /// new layer. Otherwise, will paste to the current layer.</param> /// <param name="x">Optional. Location within image to paste to. /// Position will be adjusted if pasted image would hang /// over right or bottom edges of canvas.</param> /// <param name="y">Optional. Location within image to paste to. /// Position will be adjusted if pasted image would hang /// over right or bottom edges of canvas.</param> public static void Paste(Document doc, bool toNewLayer, int x = 0, int y = 0) { // Create a compound history item for recording several // operations so that they can all be undone/redone together. var history_text = toNewLayer ? Translations.GetString("Paste Into New Layer") : Translations.GetString("Paste"); var paste_action = new CompoundHistoryItem(Resources.StandardIcons.EditPaste, history_text); var cb = Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false)); // See if the current tool wants to handle the paste // operation (e.g., the text tool could paste text) if (!toNewLayer) { if (PintaCore.Tools.DoHandlePaste(doc, cb)) { return; } } // Commit any unfinished tool actions PintaCore.Tools.Commit(); // Don't dispose this, as we're going to give it to the history Gdk.Pixbuf?cbImage = null; if (cb.WaitIsImageAvailable()) { cbImage = cb.WaitForImage(); } if (cbImage is null) { ShowClipboardEmptyDialog(); return; } var canvas_size = PintaCore.Workspace.ImageSize; // If the image being pasted is larger than the canvas size, allow the user to optionally resize the canvas if (cbImage.Width > canvas_size.Width || cbImage.Height > canvas_size.Height) { var response = ShowExpandCanvasDialog(); if (response == ResponseType.Accept) { var new_width = Math.Max(canvas_size.Width, cbImage.Width); var new_height = Math.Max(canvas_size.Height, cbImage.Height); PintaCore.Workspace.ResizeCanvas(new_width, new_height, Pinta.Core.Anchor.Center, paste_action); PintaCore.Actions.View.UpdateCanvasScale(); } else if (response == ResponseType.Cancel || response == ResponseType.DeleteEvent) { return; } } // If the pasted image would fall off bottom- or right- // side of image, adjust paste position x = Math.Max(0, Math.Min(x, canvas_size.Width - cbImage.Width)); y = Math.Max(0, Math.Min(y, canvas_size.Height - cbImage.Height)); // If requested, create a new layer, make it the current // layer and record it's creation in the history if (toNewLayer) { var l = doc.Layers.AddNewLayer(string.Empty); doc.Layers.SetCurrentUserLayer(l); paste_action.Push(new AddLayerHistoryItem(Resources.Icons.LayerNew, Translations.GetString("Add New Layer"), doc.Layers.IndexOf(l))); } // Copy the paste to the temp layer, which should be at least the size of this document. doc.Layers.CreateSelectionLayer(Math.Max(doc.ImageSize.Width, cbImage.Width), Math.Max(doc.ImageSize.Height, cbImage.Height)); doc.Layers.ShowSelectionLayer = true; using (var g = new Cairo.Context(doc.Layers.SelectionLayer.Surface)) g.DrawPixbuf(cbImage, new Cairo.Point(0, 0)); doc.Layers.SelectionLayer.Transform.InitIdentity(); doc.Layers.SelectionLayer.Transform.Translate(x, y); PintaCore.Tools.SetCurrentTool("MoveSelectedTool"); var old_selection = doc.Selection.Clone(); doc.Selection.CreateRectangleSelection(new Cairo.Rectangle(x, y, cbImage.Width, cbImage.Height)); doc.Selection.Visible = true; doc.Workspace.Invalidate(); paste_action.Push(new PasteHistoryItem(cbImage, old_selection)); doc.History.PushNewItem(paste_action); }