From c9714ff507dbff2e544ce2818a94c7efca8befbd Mon Sep 17 00:00:00 2001 From: Nathan Brown Date: Thu, 25 Nov 2021 20:33:36 -0800 Subject: [PATCH] Refactor Align/Stack function to use existing functionality. Also make undoable. --- src/Greenshot.Base/Interfaces/ISurface.cs | 2 + .../Interfaces/SurfaceExpandedEventHandler.cs | 27 ++++ .../Drawing/DrawableContainerList.cs | 139 ++++++++++++------ src/Greenshot.Editor/Drawing/Surface.cs | 15 ++ src/Greenshot.Editor/Forms/ImageEditorForm.cs | 9 ++ 5 files changed, 147 insertions(+), 45 deletions(-) create mode 100644 src/Greenshot.Base/Interfaces/SurfaceExpandedEventHandler.cs diff --git a/src/Greenshot.Base/Interfaces/ISurface.cs b/src/Greenshot.Base/Interfaces/ISurface.cs index 7b8d6884e..709e4bf6e 100644 --- a/src/Greenshot.Base/Interfaces/ISurface.cs +++ b/src/Greenshot.Base/Interfaces/ISurface.cs @@ -38,6 +38,7 @@ namespace Greenshot.Base.Interfaces event SurfaceMessageEventHandler SurfaceMessage; event SurfaceDrawingModeEventHandler DrawingModeChanged; event SurfaceElementEventHandler MovingElementChanged; + event SurfaceExpandedEventHandler SurfaceExpanded; /// /// Start value of the step-labels (counts) @@ -161,6 +162,7 @@ namespace Greenshot.Base.Interfaces void RemoveElement(IDrawableContainer elementToRemove, bool makeUndoable = true, bool invalidate = true, bool generateEvents = true); void SendMessageEvent(object source, SurfaceMessageTyp messageType, string message); + void ResizeCanvas(int left, int right, int top, int bottom); void ApplyBitmapEffect(IEffect effect); void RemoveCursor(); bool HasCursor { get; } diff --git a/src/Greenshot.Base/Interfaces/SurfaceExpandedEventHandler.cs b/src/Greenshot.Base/Interfaces/SurfaceExpandedEventHandler.cs new file mode 100644 index 000000000..b34f2179d --- /dev/null +++ b/src/Greenshot.Base/Interfaces/SurfaceExpandedEventHandler.cs @@ -0,0 +1,27 @@ +/* + * Greenshot - a free and open source screenshot tool + * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom + * + * For more information see: https://getgreenshot.org/ + * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using System; + +namespace Greenshot.Base.Interfaces +{ + public delegate void SurfaceExpandedEventHandler(object sender, EventArgs e); +} \ No newline at end of file diff --git a/src/Greenshot.Editor/Drawing/DrawableContainerList.cs b/src/Greenshot.Editor/Drawing/DrawableContainerList.cs index 1e5129a9a..e822337ce 100644 --- a/src/Greenshot.Editor/Drawing/DrawableContainerList.cs +++ b/src/Greenshot.Editor/Drawing/DrawableContainerList.cs @@ -882,52 +882,101 @@ namespace Greenshot.Editor.Drawing public void AlignOrStack(string direction, ISurface surface, IDrawableContainer target, IDrawableContainerList parent) { - int newBackgroundWidth = 0, newBackgroundHeight = 0, imageBorder = 0, xMovement = 0, yMovement = 0; - int oldImageX = 0, oldImageY = 0; - // Calculate height and width of new frame. - // Also calculate movement for target object and old image. - if (direction == "right" || direction == "left") - { - newBackgroundWidth = target.Width + surface.Image.Width; - newBackgroundHeight = Math.Max(surface.Image.Height, target.Height); - if (direction == "right") - imageBorder = surface.Image.Width; - if (direction == "left") - oldImageX = target.Width; - } + // Make calculations + int left = 0, right = 0, top = 0, bottom = 0; + if (direction == "left") + left = target.Width; + else if (direction == "right") + right = target.Width; + else if (direction == "top") + top = target.Height; + else if (direction == "bottom") + bottom = target.Height; + + // Use surface function + surface.ResizeCanvas(left, right, top, bottom); + + // Move target object + SnapToEdge(direction, surface, target); + if (direction == "left" || direction == "right") + SnapToEdge("top", surface, target); else if (direction == "top" || direction == "bottom") - { - newBackgroundWidth = Math.Max(surface.Image.Width, target.Width); - newBackgroundHeight = target.Height + surface.Image.Height; - if (direction == "top") - oldImageY = target.Height; - if (direction == "bottom") - imageBorder = surface.Image.Height; - } - // Create image for use as new frame. - Bitmap newImage = new Bitmap(newBackgroundWidth, newBackgroundHeight); - // Save old image. - Bitmap oldImage = (Bitmap)ImageHelper.Clone(surface.Image); - // Set background to new, larger frame. - surface.Image = newImage; - if (direction == "right" || direction == "left") - { - xMovement = imageBorder - target.Location.X; - yMovement = -target.Location.Y; - } - else if (direction == "top" || direction == "bottom") - { - xMovement = -target.Location.X; - yMovement = imageBorder - target.Location.Y; - } - // Move object to open space - target.MoveBy(xMovement, yMovement); - // Push original image to bottom. - var oldImageContainer = surface.AddImageContainer(oldImage, oldImageX, oldImageY); - IDrawableContainerList oldImageContainerList = parent.Clone(); - oldImageContainerList[0] = oldImageContainer; - surface.Elements.PushElementsToBottom(oldImageContainerList); - //_surfaceSizeChanged(this, null); + SnapToEdge("left", surface, target); + surface.DeselectAllElements(); + + //if (direction == "left") + //{ + // left = target.Width; + // bottom = Math.Max(target.Height - surface.Image.Height, 0); + // xMovement = -target.Location.X; + // yMovement = -target.Location.Y; + //} + //else if (direction == "right") + //{ + // right = target.Width; + // bottom = Math.Max(target.Height - surface.Image.Height, 0); + // xMovement = surface.Image.Width - target.Location.X; + // yMovement = -target.Location.Y; + //} + //else if (direction == "top") + //{ + // top = target.Height; + // right = Math.Max(target.Width - surface.Image.Width, 0); + //} + //else if (direction == "bottom") + //{ + // bottom = target.Height; + // right = Math.Max(target.Width - surface.Image.Width, 0); + //} + + + + //int newBackgroundWidth = 0, newBackgroundHeight = 0, imageBorder = 0; + //int oldImageX = 0, oldImageY = 0; + //// Calculate height and width of new frame. + //// Also calculate movement for target object and old image. + //if (direction == "right" || direction == "left") + //{ + // newBackgroundWidth = target.Width + surface.Image.Width; + // newBackgroundHeight = Math.Max(surface.Image.Height, target.Height); + // if (direction == "right") + // imageBorder = surface.Image.Width; + // if (direction == "left") + // oldImageX = target.Width; + //} + //else if (direction == "top" || direction == "bottom") + //{ + // newBackgroundWidth = Math.Max(surface.Image.Width, target.Width); + // newBackgroundHeight = target.Height + surface.Image.Height; + // if (direction == "top") + // oldImageY = target.Height; + // if (direction == "bottom") + // imageBorder = surface.Image.Height; + //} + //// Create image for use as new frame. + //Bitmap newImage = new Bitmap(newBackgroundWidth, newBackgroundHeight); + //// Save old image. + //Bitmap oldImage = (Bitmap)ImageHelper.Clone(surface.Image); + //// Set background to new, larger frame. + //surface.Image = newImage; + //if (direction == "right" || direction == "left") + //{ + // xMovement = imageBorder - target.Location.X; + // yMovement = -target.Location.Y; + //} + //else if (direction == "top" || direction == "bottom") + //{ + // xMovement = -target.Location.X; + // yMovement = imageBorder - target.Location.Y; + //} + //// Move object to open space + //target.MoveBy(xMovement, yMovement); + //// Push original image to bottom. + //var oldImageContainer = surface.AddImageContainer(oldImage, oldImageX, oldImageY); + //IDrawableContainerList oldImageContainerList = parent.Clone(); + //oldImageContainerList[0] = oldImageContainer; + //surface.Elements.PushElementsToBottom(oldImageContainerList); + ////_surfaceSizeChanged(this, null); } } } \ No newline at end of file diff --git a/src/Greenshot.Editor/Drawing/Surface.cs b/src/Greenshot.Editor/Drawing/Surface.cs index 7fd7485d0..b027ce427 100644 --- a/src/Greenshot.Editor/Drawing/Surface.cs +++ b/src/Greenshot.Editor/Drawing/Surface.cs @@ -104,6 +104,14 @@ namespace Greenshot.Editor.Drawing remove => _surfaceSizeChanged -= value; } + [NonSerialized] private SurfaceExpandedEventHandler _surfaceExpanded; + + public event SurfaceExpandedEventHandler SurfaceExpanded + { + add => _surfaceExpanded += value; + remove => _surfaceExpanded -= value; + } + [NonSerialized] private SurfaceMessageEventHandler _surfaceMessage; public event SurfaceMessageEventHandler SurfaceMessage @@ -964,6 +972,13 @@ namespace Greenshot.Editor.Drawing } } + public void ResizeCanvas(int left, int right, int top, int bottom) + { + var resizeEffect = new ResizeCanvasEffect(left, right, top, bottom); + ApplyBitmapEffect(resizeEffect); + _surfaceExpanded(this, null); + } + /// /// Apply a bitmap effect to the surface /// diff --git a/src/Greenshot.Editor/Forms/ImageEditorForm.cs b/src/Greenshot.Editor/Forms/ImageEditorForm.cs index e3b65b980..e8a95bfee 100644 --- a/src/Greenshot.Editor/Forms/ImageEditorForm.cs +++ b/src/Greenshot.Editor/Forms/ImageEditorForm.cs @@ -229,6 +229,7 @@ namespace Greenshot.Editor.Forms _surface.MovingElementChanged += delegate { RefreshEditorControls(); }; _surface.DrawingModeChanged += Surface_DrawingModeChanged; _surface.SurfaceSizeChanged += SurfaceSizeChanged; + _surface.SurfaceExpanded += SurfaceExpanded; _surface.SurfaceMessage += SurfaceMessageReceived; _surface.FieldAggregator.FieldChanged += FieldAggregatorFieldChanged; SurfaceSizeChanged(Surface, null); @@ -514,6 +515,14 @@ namespace Greenshot.Editor.Forms AlignCanvasPositionAfterResize(); } + /// + /// Used when expanding the surface in one direction to accomodate shifting an object to one side. + /// + private void SurfaceExpanded(object sender, EventArgs e) + { + UpdateUndoRedoSurfaceDependencies(); + } + public ISurface Surface { get { return _surface; }