From 75c38ba8439845c8b72379ca7cf99fa4daff5789 Mon Sep 17 00:00:00 2001 From: Jaex Date: Fri, 19 Sep 2014 22:55:31 +0300 Subject: [PATCH] Surface update --- GreenshotImageEditor/Drawing/Surface.cs | 584 ++++++++++-------- GreenshotImageEditor/Forms/ImageEditorForm.cs | 9 + .../GreenshotImageEditor.csproj | 1 - .../Properties/AssemblyInfo.cs | 2 +- 4 files changed, 339 insertions(+), 257 deletions(-) diff --git a/GreenshotImageEditor/Drawing/Surface.cs b/GreenshotImageEditor/Drawing/Surface.cs index 6ae1770eb..265f7b158 100644 --- a/GreenshotImageEditor/Drawing/Surface.cs +++ b/GreenshotImageEditor/Drawing/Surface.cs @@ -19,6 +19,7 @@ * along with this program. If not, see . */ +using Greenshot.Configuration; using Greenshot.Core; using Greenshot.Drawing.Fields; using Greenshot.Helpers; @@ -71,55 +72,55 @@ public Guid ID /// Event handlers (do not serialize!) /// [NonSerialized] - private SurfaceElementEventHandler movingElementChanged; + private SurfaceElementEventHandler _movingElementChanged; public event SurfaceElementEventHandler MovingElementChanged { add { - movingElementChanged += value; + _movingElementChanged += value; } remove { - movingElementChanged -= value; + _movingElementChanged -= value; } } [NonSerialized] - private SurfaceDrawingModeEventHandler drawingModeChanged; + private SurfaceDrawingModeEventHandler _drawingModeChanged; public event SurfaceDrawingModeEventHandler DrawingModeChanged { add { - drawingModeChanged += value; + _drawingModeChanged += value; } remove { - drawingModeChanged -= value; + _drawingModeChanged -= value; } } [NonSerialized] - private SurfaceSizeChangeEventHandler surfaceSizeChanged; + private SurfaceSizeChangeEventHandler _surfaceSizeChanged; public event SurfaceSizeChangeEventHandler SurfaceSizeChanged { add { - surfaceSizeChanged += value; + _surfaceSizeChanged += value; } remove { - surfaceSizeChanged -= value; + _surfaceSizeChanged -= value; } } [NonSerialized] - private SurfaceMessageEventHandler surfaceMessage; + private SurfaceMessageEventHandler _surfaceMessage; public event SurfaceMessageEventHandler SurfaceMessage { add { - surfaceMessage += value; + _surfaceMessage += value; } remove { - surfaceMessage -= value; + _surfaceMessage -= value; } } @@ -127,102 +128,97 @@ public Guid ID /// inUndoRedo makes sure we don't undo/redo while in a undo/redo action /// [NonSerialized] - private bool inUndoRedo = false; + private bool _inUndoRedo; /// /// Make only one surfacemove cycle undoable, see SurfaceMouseMove /// [NonSerialized] - private bool isSurfaceMoveMadeUndoable = false; + private bool _isSurfaceMoveMadeUndoable; /// /// Undo/Redo stacks, should not be serialized as the file would be way to big /// [NonSerialized] - private Stack undoStack = new Stack(); + private readonly Stack _undoStack = new Stack(); [NonSerialized] - private Stack redoStack = new Stack(); + private readonly Stack _redoStack = new Stack(); /// /// Last save location, do not serialize! /// [NonSerialized] - private string lastSaveFullPath = null; + private string _lastSaveFullPath; /// /// current drawing mode, do not serialize! /// [NonSerialized] - private DrawingModes drawingMode = DrawingModes.None; + private DrawingModes _drawingMode = DrawingModes.None; /// /// the keyslocked flag helps with focus issues /// [NonSerialized] - private bool keysLocked = false; + private bool _keysLocked; /// /// Location of the mouse-down (it "starts" here), do not serialize /// [NonSerialized] - private Point mouseStart = Point.Empty; + private Point _mouseStart = Point.Empty; /// /// are we in a mouse down, do not serialize /// [NonSerialized] - private bool mouseDown = false; - - /// - /// are we dragging, do not serialize - /// - [NonSerialized] - private bool draggingInProgress = false; + private bool _mouseDown; /// /// The selected element for the mouse down, do not serialize /// [NonSerialized] - private IDrawableContainer mouseDownElement = null; + private IDrawableContainer _mouseDownElement; /// /// all selected elements, do not serialize /// [NonSerialized] - private DrawableContainerList selectedElements = new DrawableContainerList(); + private DrawableContainerList selectedElements; /// /// the element we are drawing with, do not serialize /// [NonSerialized] - private IDrawableContainer drawingElement = null; + private IDrawableContainer _drawingElement; /// /// the element we want to draw with (not yet drawn), do not serialize /// [NonSerialized] - private IDrawableContainer _undrawnElement = null; + private IDrawableContainer _undrawnElement; /// /// the cropcontainer, when cropping this is set, do not serialize /// [NonSerialized] - private IDrawableContainer cropContainer = null; + private IDrawableContainer _cropContainer; /// /// the brush which is used for transparent backgrounds, set by the editor, do not serialize /// [NonSerialized] - private Brush transparencyBackgroundBrush; + private Brush _transparencyBackgroundBrush; /// /// The buffer is only for drawing on it when using filters (to supply access) /// This saves a lot of "create new bitmap" commands /// Should not be serialized, as it's generated. /// The actual bitmap is in the paintbox... + /// TODO: Check if this buffer is still needed! /// [NonSerialized] - private Bitmap buffer = null; + private Bitmap _buffer; /// /// all stepLabels for the surface, needed with serialization @@ -264,22 +260,22 @@ public int CountStepLabels(IDrawableContainer stopAtContainer) /// /// all elements on the surface, needed with serialization /// - private DrawableContainerList elements = new DrawableContainerList(); + private readonly DrawableContainerList _elements; /// /// all elements on the surface, needed with serialization /// - private FieldAggregator fieldAggregator = new FieldAggregator(); + private FieldAggregator _fieldAggregator = new FieldAggregator(); /// /// the cursor container, needed with serialization as we need a direct acces to it. /// - private IDrawableContainer cursorContainer = null; + private IDrawableContainer _cursorContainer; /// /// the capture details, needed with serialization /// - private ICaptureDetails captureDetails = null; + private ICaptureDetails _captureDetails; /// /// the modified flag specifies if the surface has had modifications after the last export. @@ -287,22 +283,22 @@ public int CountStepLabels(IDrawableContainer stopAtContainer) /// After serialization this should actually be "false" (the surface came from a stream) /// For now we just serialize it... /// - private bool modified = true; + private bool _modified = true; /// /// The image is the actual captured image, needed with serialization /// - private Image image = null; + private Image _image; public Image Image { get { - return image; + return _image; } set { - image = value; - Size = image.Size; + _image = value; + Size = _image.Size; } } @@ -314,11 +310,11 @@ public FieldAggregator FieldAggregator { get { - return fieldAggregator; + return _fieldAggregator; } set { - fieldAggregator = value; + _fieldAggregator = value; } } @@ -329,7 +325,7 @@ public IDrawableContainer CursorContainer { get { - return cursorContainer; + return _cursorContainer; } } @@ -340,7 +336,7 @@ public bool HasCursor { get { - return cursorContainer != null; + return _cursorContainer != null; } } @@ -349,8 +345,8 @@ public bool HasCursor /// public void RemoveCursor() { - RemoveElement(cursorContainer, true); - cursorContainer = null; + RemoveElement(_cursorContainer, true); + _cursorContainer = null; } /// @@ -360,11 +356,11 @@ public Brush TransparencyBackgroundBrush { get { - return transparencyBackgroundBrush; + return _transparencyBackgroundBrush; } set { - transparencyBackgroundBrush = value; + _transparencyBackgroundBrush = value; } } @@ -375,11 +371,11 @@ public bool KeysLocked { get { - return keysLocked; + return _keysLocked; } set { - keysLocked = value; + _keysLocked = value; } } @@ -390,11 +386,11 @@ public bool Modified { get { - return modified; + return _modified; } set { - modified = value; + _modified = value; } } @@ -405,16 +401,16 @@ public DrawingModes DrawingMode { get { - return drawingMode; + return _drawingMode; } set { - drawingMode = value; - if (drawingModeChanged != null) + _drawingMode = value; + if (_drawingModeChanged != null) { SurfaceDrawingModeEventArgs eventArgs = new SurfaceDrawingModeEventArgs(); - eventArgs.DrawingMode = drawingMode; - drawingModeChanged.Invoke(this, eventArgs); + eventArgs.DrawingMode = _drawingMode; + _drawingModeChanged.Invoke(this, eventArgs); } DeselectAllElements(); CreateUndrawnElement(); @@ -428,11 +424,11 @@ public string LastSaveFullPath { get { - return lastSaveFullPath; + return _lastSaveFullPath; } set { - lastSaveFullPath = value; + _lastSaveFullPath = value; } } @@ -452,11 +448,11 @@ public ICaptureDetails CaptureDetails { get { - return captureDetails; + return _captureDetails; } set { - captureDetails = value; + _captureDetails = value; } } @@ -467,6 +463,8 @@ public Surface() : base() { Count++; + _elements = new DrawableContainerList(_uniqueId); + selectedElements = new DrawableContainerList(_uniqueId); LOG.Debug("Creating surface!"); MouseDown += SurfaceMouseDown; MouseUp += SurfaceMouseUp; @@ -478,7 +476,7 @@ public Surface() DragEnter += OnDragEnter; // bind selected & elements to this, otherwise they can't inform of modifications selectedElements.Parent = this; - elements.Parent = this; + _elements.Parent = this; // Make sure we are visible Visible = true; TabStop = false; @@ -490,21 +488,21 @@ public Surface() /// /// Private method, the current image is disposed the new one will stay. /// - /// The new image + /// The new image /// true if the old image needs to be disposed, when using undo this should not be true!! private void SetImage(Image newImage, bool dispose) { // Dispose - if (image != null && dispose) + if (_image != null && dispose) { - image.Dispose(); + _image.Dispose(); } // Set new values Image = newImage; Size = newImage.Size; - modified = true; + _modified = true; } /// @@ -533,14 +531,14 @@ public Surface(ICapture capture) // check if cursor is on the capture, otherwise we leave it out. if (cursorRect.IntersectsWith(captureRect)) { - cursorContainer = AddIconContainer(capture.Cursor, capture.CursorLocation.X, capture.CursorLocation.Y); - SelectElement(cursorContainer); + _cursorContainer = AddIconContainer(capture.Cursor, capture.CursorLocation.X, capture.CursorLocation.Y); + SelectElement(_cursorContainer); } } // Make sure the image is NOT disposed, we took the reference directly into ourselves ((Capture)capture).NullImage(); - captureDetails = capture.CaptureDetails; + _captureDetails = capture.CaptureDetails; } protected override void Dispose(bool disposing) @@ -549,27 +547,27 @@ protected override void Dispose(bool disposing) { Count--; LOG.Debug("Disposing surface!"); - if (buffer != null) + if (_buffer != null) { - buffer.Dispose(); - buffer = null; + _buffer.Dispose(); + _buffer = null; } - if (transparencyBackgroundBrush != null) + if (_transparencyBackgroundBrush != null) { - transparencyBackgroundBrush.Dispose(); - transparencyBackgroundBrush = null; + _transparencyBackgroundBrush.Dispose(); + _transparencyBackgroundBrush = null; } // Cleanup undo/redo stacks - while (undoStack != null && undoStack.Count > 0) + while (_undoStack != null && _undoStack.Count > 0) { - undoStack.Pop().Dispose(); + _undoStack.Pop().Dispose(); } - while (redoStack != null && redoStack.Count > 0) + while (_redoStack != null && _redoStack.Count > 0) { - redoStack.Pop().Dispose(); + _redoStack.Pop().Dispose(); } - foreach (IDrawableContainer container in elements) + foreach (IDrawableContainer container in _elements) { container.Dispose(); } @@ -578,10 +576,10 @@ protected override void Dispose(bool disposing) _undrawnElement.Dispose(); _undrawnElement = null; } - if (cropContainer != null) + if (_cropContainer != null) { - cropContainer.Dispose(); - cropContainer = null; + _cropContainer.Dispose(); + _cropContainer = null; } } base.Dispose(disposing); @@ -592,12 +590,12 @@ protected override void Dispose(bool disposing) /// public void Undo() { - if (undoStack.Count > 0) + if (_undoStack.Count > 0) { - inUndoRedo = true; - IMemento top = undoStack.Pop(); - redoStack.Push(top.Restore()); - inUndoRedo = false; + _inUndoRedo = true; + IMemento top = _undoStack.Pop(); + _redoStack.Push(top.Restore()); + _inUndoRedo = false; } } @@ -606,12 +604,12 @@ public void Undo() /// public void Redo() { - if (redoStack.Count > 0) + if (_redoStack.Count > 0) { - inUndoRedo = true; - IMemento top = redoStack.Pop(); - undoStack.Push(top.Restore()); - inUndoRedo = false; + _inUndoRedo = true; + IMemento top = _redoStack.Pop(); + _undoStack.Push(top.Restore()); + _inUndoRedo = false; } } @@ -622,7 +620,7 @@ public bool CanUndo { get { - return undoStack.Count > 0; + return _undoStack.Count > 0; } } @@ -633,7 +631,7 @@ public bool CanRedo { get { - return redoStack.Count > 0; + return _redoStack.Count > 0; } } @@ -641,28 +639,29 @@ public bool CanRedo /// Make an action undo-able /// /// The memento implementing the undo + /// Allow changes to be merged public void MakeUndoable(IMemento memento, bool allowMerge) { - if (inUndoRedo) + if (_inUndoRedo) { throw new InvalidOperationException("Invoking do within an undo/redo action."); } if (memento != null) { bool allowPush = true; - if (undoStack.Count > 0 && allowMerge) + if (_undoStack.Count > 0 && allowMerge) { // Check if merge is possible - allowPush = !undoStack.Peek().Merge(memento); + allowPush = !_undoStack.Peek().Merge(memento); } if (allowPush) { // Clear the redo-stack and dispose - while (redoStack.Count > 0) + while (_redoStack.Count > 0) { - redoStack.Pop().Dispose(); + _redoStack.Pop().Dispose(); } - undoStack.Push(memento); + _undoStack.Push(memento); } } } @@ -680,7 +679,7 @@ public long SaveElementsToStream(Stream streamWrite) { long lengtBefore = streamWrite.Length; BinaryFormatter binaryWrite = new BinaryFormatter(); - binaryWrite.Serialize(streamWrite, elements); + binaryWrite.Serialize(streamWrite, _elements); bytesWritten = streamWrite.Length - lengtBefore; } catch (Exception e) @@ -758,8 +757,8 @@ private void CreateUndrawnElement() _undrawnElement = new ObfuscateContainer(this); break; case DrawingModes.Crop: - cropContainer = new CropContainer(this); - _undrawnElement = cropContainer; + _cropContainer = new CropContainer(this); + _undrawnElement = _cropContainer; break; case DrawingModes.Bitmap: _undrawnElement = new ImageContainer(this); @@ -875,7 +874,7 @@ private void OnDragEnter(object sender, DragEventArgs e) LOG.Debug(format); } } - if (draggingInProgress || (e.AllowedEffect & DragDropEffects.Copy) != DragDropEffects.Copy) + if ((e.AllowedEffect & DragDropEffects.Copy) != DragDropEffects.Copy) { e.Effect = DragDropEffects.None; } @@ -899,7 +898,6 @@ private void OnDragEnter(object sender, DragEventArgs e) /// private void OnDragDrop(object sender, DragEventArgs e) { - List filenames = ClipboardHelper.GetImageFilenames(e.Data); Point mouse = PointToClient(new Point(e.X, e.Y)); foreach (Image image in ClipboardHelper.GetImages(e.Data)) @@ -910,17 +908,6 @@ private void OnDragDrop(object sender, DragEventArgs e) } } - // private void QueryContinueDragDrop(object sender, QueryContinueDragEventArgs e) { - // LOG.Debug("QueryContinueDrag: " + e.Action); - // if (e.EscapePressed) { - // e.Action = DragAction.Cancel; - // } - // } - // - // private void GiveFeedbackDragDrop(object sender, GiveFeedbackEventArgs e) { - // e.UseDefaultCursors = true; - // } - #endregion DragDrop /// @@ -929,25 +916,29 @@ private void OnDragDrop(object sender, DragEventArgs e) /// true if cropped public bool AutoCrop() { - Rectangle cropRectangle = ImageHelper.FindAutoCropRectangle(Image, conf.AutoCropDifference); - if (isCropPossible(ref cropRectangle)) + Rectangle cropRectangle; + using (Image tmpImage = GetImageForExport()) { - DeselectAllElements(); - // Maybe a bit obscure, but the following line creates a drop container - // It's available as "undrawnElement" - DrawingMode = DrawingModes.Crop; - _undrawnElement.Left = cropRectangle.X; - _undrawnElement.Top = cropRectangle.Y; - _undrawnElement.Width = cropRectangle.Width; - _undrawnElement.Height = cropRectangle.Height; - _undrawnElement.Status = EditStatus.UNDRAWN; - AddElement(_undrawnElement); - SelectElement(_undrawnElement); - drawingElement = null; - _undrawnElement = null; - return true; + cropRectangle = ImageHelper.FindAutoCropRectangle(tmpImage, conf.AutoCropDifference); } - return false; + if (!IsCropPossible(ref cropRectangle)) + { + return false; + } + DeselectAllElements(); + // Maybe a bit obscure, but the following line creates a drop container + // It's available as "undrawnElement" + DrawingMode = DrawingModes.Crop; + _undrawnElement.Left = cropRectangle.X; + _undrawnElement.Top = cropRectangle.Y; + _undrawnElement.Width = cropRectangle.Width; + _undrawnElement.Height = cropRectangle.Height; + _undrawnElement.Status = EditStatus.UNDRAWN; + AddElement(_undrawnElement); + SelectElement(_undrawnElement); + _drawingElement = null; + _undrawnElement = null; + return true; } /// @@ -984,14 +975,14 @@ public void ApplyBitmapEffect(IEffect effect) if (newImage != null) { // Make sure the elements move according to the offset the effect made the bitmap move - elements.Transform(matrix); + _elements.Transform(matrix); // Make undoable MakeUndoable(new SurfaceBackgroundChangeMemento(this, matrix), false); SetImage(newImage, false); Invalidate(); - if (surfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, newImage.Size))) + if (_surfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, newImage.Size))) { - surfaceSizeChanged(this, null); + _surfaceSizeChanged(this, null); } } else @@ -1012,7 +1003,7 @@ public void ApplyBitmapEffect(IEffect effect) /// /// /// true if this is possible - public bool isCropPossible(ref Rectangle cropRectangle) + public bool IsCropPossible(ref Rectangle cropRectangle) { cropRectangle = GuiRectangle.GetGuiRectangle(cropRectangle.Left, cropRectangle.Top, cropRectangle.Width, cropRectangle.Height); if (cropRectangle.Left < 0) @@ -1046,13 +1037,13 @@ public bool isCropPossible(ref Rectangle cropRectangle) /// Message itself public void SendMessageEvent(object source, SurfaceMessageTyp messageType, string message) { - if (surfaceMessage != null) + if (_surfaceMessage != null) { SurfaceMessageEventArgs eventArgs = new SurfaceMessageEventArgs(); eventArgs.Message = message; eventArgs.MessageType = messageType; eventArgs.Surface = this; - surfaceMessage(source, eventArgs); + _surfaceMessage(source, eventArgs); } } @@ -1063,7 +1054,7 @@ public void SendMessageEvent(object source, SurfaceMessageTyp messageType, strin /// public bool ApplyCrop(Rectangle cropRectangle) { - if (isCropPossible(ref cropRectangle)) + if (IsCropPossible(ref cropRectangle)) { Rectangle imageRectangle = new Rectangle(Point.Empty, Image.Size); Bitmap tmpImage; @@ -1088,10 +1079,10 @@ public bool ApplyCrop(Rectangle cropRectangle) // Do not dispose otherwise we can't undo the image! SetImage(tmpImage, false); - elements.Transform(matrix); - if (surfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, tmpImage.Size))) + _elements.Transform(matrix); + if (_surfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, tmpImage.Size))) { - surfaceSizeChanged(this, null); + _surfaceSizeChanged(this, null); } Invalidate(); return true; @@ -1110,11 +1101,11 @@ public void UndoBackgroundChange(Image previous, Matrix matrix) SetImage(previous, false); if (matrix != null) { - elements.Transform(matrix); + _elements.Transform(matrix); } - if (surfaceSizeChanged != null) + if (_surfaceSizeChanged != null) { - surfaceSizeChanged(this, null); + _surfaceSizeChanged(this, null); } Invalidate(); } @@ -1126,7 +1117,7 @@ public void UndoBackgroundChange(Image previous, Matrix matrix) /// private void SurfaceMouseDown(object sender, MouseEventArgs e) { - mouseStart = e.Location; + _mouseStart = e.Location; // check contextmenu if (e.Button == MouseButtons.Right) @@ -1139,10 +1130,10 @@ private void SurfaceMouseDown(object sender, MouseEventArgs e) else { // Single element - IDrawableContainer rightClickedContainer = elements.ClickableElementAt(mouseStart.X, mouseStart.Y); + IDrawableContainer rightClickedContainer = _elements.ClickableElementAt(_mouseStart.X, _mouseStart.Y); if (rightClickedContainer != null) { - selectedList = new DrawableContainerList(); + selectedList = new DrawableContainerList(ID); selectedList.Add(rightClickedContainer); } } @@ -1153,17 +1144,17 @@ private void SurfaceMouseDown(object sender, MouseEventArgs e) return; } - mouseDown = true; - isSurfaceMoveMadeUndoable = false; + _mouseDown = true; + _isSurfaceMoveMadeUndoable = false; - if (cropContainer != null && ((_undrawnElement == null) || (_undrawnElement != null && DrawingMode != DrawingModes.Crop))) + if (_cropContainer != null && ((_undrawnElement == null) || (_undrawnElement != null && DrawingMode != DrawingModes.Crop))) { - RemoveElement(cropContainer, false); - cropContainer = null; - drawingElement = null; + RemoveElement(_cropContainer, false); + _cropContainer = null; + _drawingElement = null; } - if (drawingElement == null && DrawingMode != DrawingModes.None) + if (_drawingElement == null && DrawingMode != DrawingModes.None) { if (_undrawnElement == null) { @@ -1173,32 +1164,32 @@ private void SurfaceMouseDown(object sender, MouseEventArgs e) CreateUndrawnElement(); } } - drawingElement = _undrawnElement; - drawingElement.Status = EditStatus.DRAWING; - _undrawnElement = null; + _drawingElement = _undrawnElement; // if a new element has been drawn, set location and register it - if (drawingElement != null) + if (_drawingElement != null) { - drawingElement.PropertyChanged += ElementPropertyChanged; - if (!drawingElement.HandleMouseDown(mouseStart.X, mouseStart.Y)) + _drawingElement.Status = _undrawnElement.DefaultEditMode; + _drawingElement.PropertyChanged += ElementPropertyChanged; + if (!_drawingElement.HandleMouseDown(_mouseStart.X, _mouseStart.Y)) { - drawingElement.Left = mouseStart.X; - drawingElement.Top = mouseStart.Y; + _drawingElement.Left = _mouseStart.X; + _drawingElement.Top = _mouseStart.Y; } - AddElement(drawingElement); - drawingElement.Selected = true; + AddElement(_drawingElement); + _drawingElement.Selected = true; } + _undrawnElement = null; } else { // check whether an existing element was clicked // we save mouse down element separately from selectedElements (checked on mouse up), // since it could be moved around before it is actually selected - mouseDownElement = elements.ClickableElementAt(mouseStart.X, mouseStart.Y); + _mouseDownElement = _elements.ClickableElementAt(_mouseStart.X, _mouseStart.Y); - if (mouseDownElement != null) + if (_mouseDownElement != null) { - mouseDownElement.Status = EditStatus.MOVING; + _mouseDownElement.Status = EditStatus.MOVING; } } } @@ -1212,17 +1203,17 @@ private void SurfaceMouseUp(object sender, MouseEventArgs e) { Point currentMouse = new Point(e.X, e.Y); - elements.Status = EditStatus.IDLE; - if (mouseDownElement != null) + _elements.Status = EditStatus.IDLE; + if (_mouseDownElement != null) { - mouseDownElement.Status = EditStatus.IDLE; + _mouseDownElement.Status = EditStatus.IDLE; } - mouseDown = false; - mouseDownElement = null; + _mouseDown = false; + _mouseDownElement = null; if (DrawingMode == DrawingModes.None) { // check whether an existing element was clicked - IDrawableContainer element = elements.ClickableElementAt(currentMouse.X, currentMouse.Y); + IDrawableContainer element = _elements.ClickableElementAt(currentMouse.X, currentMouse.Y); bool shiftModifier = (ModifierKeys & Keys.Shift) == Keys.Shift; if (element != null) { @@ -1260,26 +1251,26 @@ private void SurfaceMouseUp(object sender, MouseEventArgs e) selectedElements.Selected = true; } - if (drawingElement != null) + if (_drawingElement != null) { - if (!drawingElement.InitContent()) + if (!_drawingElement.InitContent()) { - elements.Remove(drawingElement); - drawingElement.Invalidate(); + _elements.Remove(_drawingElement); + _drawingElement.Invalidate(); } else { - drawingElement.HandleMouseUp(currentMouse.X, currentMouse.Y); - drawingElement.Invalidate(); - if (Math.Abs(drawingElement.Width) < 5 && Math.Abs(drawingElement.Height) < 5) + _drawingElement.HandleMouseUp(currentMouse.X, currentMouse.Y); + _drawingElement.Invalidate(); + if (Math.Abs(_drawingElement.Width) < 5 && Math.Abs(_drawingElement.Height) < 5) { - drawingElement.Width = 25; - drawingElement.Height = 25; + _drawingElement.Width = 25; + _drawingElement.Height = 25; } - SelectElement(drawingElement); - drawingElement.Selected = true; + SelectElement(_drawingElement); + _drawingElement.Selected = true; } - drawingElement = null; + _drawingElement = null; } } @@ -1301,43 +1292,43 @@ private void SurfaceMouseMove(object sender, MouseEventArgs e) Cursor = Cursors.Default; } - if (mouseDown) + if (_mouseDown) { - if (mouseDownElement != null) + if (_mouseDownElement != null) { // an element is currently dragged - mouseDownElement.Invalidate(); + _mouseDownElement.Invalidate(); selectedElements.HideGrippers(); // Move the element - if (mouseDownElement.Selected) + if (_mouseDownElement.Selected) { - if (!isSurfaceMoveMadeUndoable) + if (!_isSurfaceMoveMadeUndoable) { // Only allow one undoable per mouse-down/move/up "cycle" - isSurfaceMoveMadeUndoable = true; + _isSurfaceMoveMadeUndoable = true; selectedElements.MakeBoundsChangeUndoable(false); } // dragged element has been selected before -> move all - selectedElements.MoveBy(currentMouse.X - mouseStart.X, currentMouse.Y - mouseStart.Y); + selectedElements.MoveBy(currentMouse.X - _mouseStart.X, currentMouse.Y - _mouseStart.Y); } else { - if (!isSurfaceMoveMadeUndoable) + if (!_isSurfaceMoveMadeUndoable) { // Only allow one undoable per mouse-down/move/up "cycle" - isSurfaceMoveMadeUndoable = true; - mouseDownElement.MakeBoundsChangeUndoable(false); + _isSurfaceMoveMadeUndoable = true; + _mouseDownElement.MakeBoundsChangeUndoable(false); } // dragged element is not among selected elements -> just move dragged one - mouseDownElement.MoveBy(currentMouse.X - mouseStart.X, currentMouse.Y - mouseStart.Y); + _mouseDownElement.MoveBy(currentMouse.X - _mouseStart.X, currentMouse.Y - _mouseStart.Y); } - mouseStart = currentMouse; - mouseDownElement.Invalidate(); - modified = true; + _mouseStart = currentMouse; + _mouseDownElement.Invalidate(); + _modified = true; } - else if (drawingElement != null) + else if (_drawingElement != null) { - drawingElement.HandleMouseMove(currentMouse.X, currentMouse.Y); - modified = true; + _drawingElement.HandleMouseMove(currentMouse.X, currentMouse.Y); + _modified = true; } } } @@ -1361,7 +1352,7 @@ private void SurfaceDoubleClick(object sender, MouseEventArgs e) private Image GetImage(RenderMode renderMode) { // Generate a copy of the original image with a dpi equal to the default... - Bitmap clone = ImageHelper.Clone(image, PixelFormat.DontCare); + Bitmap clone = ImageHelper.Clone(_image, PixelFormat.DontCare); // otherwise we would have a problem drawing the image to the surface... :( using (Graphics graphics = Graphics.FromImage(clone)) { @@ -1370,7 +1361,7 @@ private Image GetImage(RenderMode renderMode) //graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; //graphics.CompositingQuality = CompositingQuality.HighQuality; //graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; - elements.Draw(graphics, clone, renderMode, new Rectangle(Point.Empty, clone.Size)); + _elements.Draw(graphics, clone, renderMode, new Rectangle(Point.Empty, clone.Size)); } return clone; } @@ -1399,23 +1390,23 @@ private void SurfacePaint(object sender, PaintEventArgs e) return; } - if (elements.HasIntersectingFilters(clipRectangle)) + if (_elements.HasIntersectingFilters(clipRectangle)) { - if (buffer != null) + if (_buffer != null) { - if (buffer.Width != Image.Width || buffer.Height != Image.Height || buffer.PixelFormat != Image.PixelFormat) + if (_buffer.Width != Image.Width || _buffer.Height != Image.Height || _buffer.PixelFormat != Image.PixelFormat) { - buffer.Dispose(); - buffer = null; + _buffer.Dispose(); + _buffer = null; } } - if (buffer == null) + if (_buffer == null) { - buffer = ImageHelper.CreateEmpty(Image.Width, Image.Height, Image.PixelFormat, Color.Empty, Image.HorizontalResolution, Image.VerticalResolution); + _buffer = ImageHelper.CreateEmpty(Image.Width, Image.Height, Image.PixelFormat, Color.Empty, Image.HorizontalResolution, Image.VerticalResolution); LOG.DebugFormat("Created buffer with size: {0}x{1}", Image.Width, Image.Height); } // Elements might need the bitmap, so we copy the part we need - using (Graphics graphics = Graphics.FromImage(buffer)) + using (Graphics graphics = Graphics.FromImage(_buffer)) { // do not set the following, the containers need to decide this themselves! //graphics.SmoothingMode = SmoothingMode.HighQuality; @@ -1424,14 +1415,14 @@ private void SurfacePaint(object sender, PaintEventArgs e) //graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel); graphics.SetClip(targetGraphics); - elements.Draw(graphics, buffer, RenderMode.EDIT, clipRectangle); + _elements.Draw(graphics, _buffer, RenderMode.EDIT, clipRectangle); } - targetGraphics.DrawImage(buffer, clipRectangle, clipRectangle, GraphicsUnit.Pixel); + targetGraphics.DrawImage(_buffer, clipRectangle, clipRectangle, GraphicsUnit.Pixel); } else { targetGraphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel); - elements.Draw(targetGraphics, null, RenderMode.EDIT, clipRectangle); + _elements.Draw(targetGraphics, null, RenderMode.EDIT, clipRectangle); } } @@ -1442,11 +1433,11 @@ private void SurfacePaint(object sender, PaintEventArgs e) protected override void OnPaintBackground(PaintEventArgs e) { // check if we need to draw the checkerboard - if (Image.IsAlphaPixelFormat(Image.PixelFormat) && transparencyBackgroundBrush != null) + if (Image.IsAlphaPixelFormat(Image.PixelFormat) && _transparencyBackgroundBrush != null) { Graphics targetGraphics = e.Graphics; Rectangle clipRectangle = e.ClipRectangle; - targetGraphics.FillRectangle(transparencyBackgroundBrush, clipRectangle); + targetGraphics.FillRectangle(_transparencyBackgroundBrush, clipRectangle); } else { @@ -1472,7 +1463,7 @@ public void AddElement(IDrawableContainer element) /// true if the adding should be undoable public void AddElement(IDrawableContainer element, bool makeUndoable) { - elements.Add(element); + _elements.Add(element); DrawableContainer container = element as DrawableContainer; if (container != null) { @@ -1488,7 +1479,7 @@ public void AddElement(IDrawableContainer element, bool makeUndoable) { MakeUndoable(new AddElementMemento(this, element), false); } - modified = true; + _modified = true; } /// @@ -1499,7 +1490,7 @@ public void AddElement(IDrawableContainer element, bool makeUndoable) public void RemoveElement(IDrawableContainer elementToRemove, bool makeUndoable) { DeselectElement(elementToRemove); - elements.Remove(elementToRemove); + _elements.Remove(elementToRemove); DrawableContainer element = elementToRemove as DrawableContainer; if (element != null) { @@ -1507,12 +1498,12 @@ public void RemoveElement(IDrawableContainer elementToRemove, bool makeUndoable) } elementToRemove.PropertyChanged -= ElementPropertyChanged; // Do not dispose, the memento should!! element.Dispose(); - elementToRemove.Invalidate(); + Invalidate(); if (makeUndoable) { MakeUndoable(new DeleteElementMemento(this, elementToRemove), false); } - modified = true; + _modified = true; } /// @@ -1560,11 +1551,11 @@ public void RemoveSelectedElements() RemoveElement(element, true); } selectedElements.Clear(); - if (movingElementChanged != null) + if (_movingElementChanged != null) { SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs(); eventArgs.Elements = selectedElements; - movingElementChanged(this, eventArgs); + _movingElementChanged(this, eventArgs); } } } @@ -1603,17 +1594,17 @@ public void ConfirmSelectedConfirmableElements(bool confirm) List selectedDCs = new List(selectedElements); foreach (IDrawableContainer dc in selectedDCs) { - if (dc.Equals(cropContainer)) + if (dc.Equals(_cropContainer)) { DrawingMode = DrawingModes.None; // No undo memento for the cropcontainer itself, only for the effect - RemoveElement(cropContainer, false); + RemoveElement(_cropContainer, false); if (confirm) { - ApplyCrop(cropContainer.Bounds); + ApplyCrop(_cropContainer.Bounds); } - cropContainer.Dispose(); - cropContainer = null; + _cropContainer.Dispose(); + _cropContainer = null; } } } @@ -1644,8 +1635,91 @@ public void PasteElementFromClipboard() DrawableContainerList dcs = (DrawableContainerList)ClipboardHelper.GetFromDataObject(clipboard, typeof(DrawableContainerList)); if (dcs != null) { + // Make element(s) only move 10,10 if the surface is the same + Point moveOffset; + bool isSameSurface = (dcs.ParentID == _uniqueId); dcs.Parent = this; - dcs.MoveBy(10, 10); + if (isSameSurface) + { + moveOffset = new Point(10, 10); + } + else + { + moveOffset = Point.Empty; + } + // Here a fix for bug #1475, first calculate the bounds of the complete DrawableContainerList + Rectangle drawableContainerListBounds = Rectangle.Empty; + foreach (IDrawableContainer element in dcs) + { + if (drawableContainerListBounds == Rectangle.Empty) + { + drawableContainerListBounds = element.DrawingBounds; + } + else + { + drawableContainerListBounds = Rectangle.Union(drawableContainerListBounds, element.DrawingBounds); + } + } + // And find a location inside the target surface to paste to + bool containersCanFit = drawableContainerListBounds.Width < Bounds.Width && drawableContainerListBounds.Height < Bounds.Height; + if (!containersCanFit) + { + Point containersLocation = drawableContainerListBounds.Location; + containersLocation.Offset(moveOffset); + if (!Bounds.Contains(containersLocation)) + { + // Easy fix for same surface + if (isSameSurface) + { + moveOffset = new Point(-10, -10); + } + else + { + // For different surface, which is most likely smaller, we move to "10,10" + moveOffset = new Point(-drawableContainerListBounds.Location.X + 10, -drawableContainerListBounds.Location.Y + 10); + } + } + } + else + { + Rectangle moveContainerListBounds = drawableContainerListBounds; + moveContainerListBounds.Offset(moveOffset); + // check if the element is inside + if (!Bounds.Contains(moveContainerListBounds)) + { + // Easy fix for same surface + if (isSameSurface) + { + moveOffset = new Point(-10, -10); + } + else + { + // For different surface, which is most likely smaller + int offsetX = 0; + int offsetY = 0; + if (drawableContainerListBounds.Right > Bounds.Right) + { + offsetX = Bounds.Right - drawableContainerListBounds.Right; + // Correction for the correction + if (drawableContainerListBounds.Left + offsetX < 0) + { + offsetX += Math.Abs(drawableContainerListBounds.Left + offsetX); + } + } + if (drawableContainerListBounds.Bottom > Bounds.Bottom) + { + offsetY = Bounds.Bottom - drawableContainerListBounds.Bottom; + // Correction for the correction + if (drawableContainerListBounds.Top + offsetY < 0) + { + offsetY += Math.Abs(drawableContainerListBounds.Top + offsetY); + } + } + moveOffset = new Point(offsetX, offsetY); + } + } + } + dcs.MoveBy(moveOffset.X, moveOffset.Y); AddElements(dcs); FieldAggregator.BindElements(dcs); DeselectAllElements(); @@ -1706,11 +1780,11 @@ public void DeselectElement(IDrawableContainer container) container.Selected = false; selectedElements.Remove(container); FieldAggregator.UnbindElement(container); - if (movingElementChanged != null) + if (_movingElementChanged != null) { SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs(); eventArgs.Elements = selectedElements; - movingElementChanged(this, eventArgs); + _movingElementChanged(this, eventArgs); } } @@ -1730,11 +1804,11 @@ public void DeselectAllElements() selectedElements.Remove(element); FieldAggregator.UnbindElement(element); } - if (movingElementChanged != null) + if (_movingElementChanged != null) { SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs(); eventArgs.Elements = selectedElements; - movingElementChanged(this, eventArgs); + _movingElementChanged(this, eventArgs); } } } @@ -1751,11 +1825,11 @@ public void SelectElement(IDrawableContainer container) container.ShowGrippers(); container.Selected = true; FieldAggregator.BindElement(container); - if (movingElementChanged != null) + if (_movingElementChanged != null) { SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs(); eventArgs.Elements = selectedElements; - movingElementChanged(this, eventArgs); + _movingElementChanged(this, eventArgs); } container.Invalidate(); } @@ -1766,7 +1840,7 @@ public void SelectElement(IDrawableContainer container) /// public void SelectAllElements() { - SelectElements(elements); + SelectElements(_elements); } /// @@ -1853,7 +1927,7 @@ public DrawableContainerList Elements { get { - return elements; + return _elements; } } @@ -1862,8 +1936,8 @@ public DrawableContainerList Elements /// public void PullElementsUp() { - elements.PullElementsUp(selectedElements); - elements.Invalidate(); + _elements.PullElementsUp(selectedElements); + _elements.Invalidate(); } /// @@ -1871,8 +1945,8 @@ public void PullElementsUp() /// public void PullElementsToTop() { - elements.PullElementsToTop(selectedElements); - elements.Invalidate(); + _elements.PullElementsToTop(selectedElements); + _elements.Invalidate(); } /// @@ -1880,8 +1954,8 @@ public void PullElementsToTop() /// public void PushElementsDown() { - elements.PushElementsDown(selectedElements); - elements.Invalidate(); + _elements.PushElementsDown(selectedElements); + _elements.Invalidate(); } /// @@ -1889,8 +1963,8 @@ public void PushElementsDown() /// public void PushElementsToBottom() { - elements.PushElementsToBottom(selectedElements); - elements.Invalidate(); + _elements.PushElementsToBottom(selectedElements); + _elements.Invalidate(); } /// @@ -1899,7 +1973,7 @@ public void PushElementsToBottom() /// true if selected elements could be pulled up, false otherwise public bool CanPullSelectionUp() { - return elements.CanPullUp(selectedElements); + return _elements.CanPullUp(selectedElements); } /// @@ -1908,7 +1982,7 @@ public bool CanPullSelectionUp() /// true if selected elements could be pushed down, false otherwise public bool CanPushSelectionDown() { - return elements.CanPushDown(selectedElements); + return _elements.CanPushDown(selectedElements); } public void ElementPropertyChanged(object sender, PropertyChangedEventArgs e) @@ -1923,7 +1997,7 @@ public void element_FieldChanged(object sender, FieldChangedEventArgs e) public bool IsOnSurface(IDrawableContainer container) { - return elements.Contains(container); + return _elements.Contains(container); } } } \ No newline at end of file diff --git a/GreenshotImageEditor/Forms/ImageEditorForm.cs b/GreenshotImageEditor/Forms/ImageEditorForm.cs index e54c7ff09..8b986abbc 100644 --- a/GreenshotImageEditor/Forms/ImageEditorForm.cs +++ b/GreenshotImageEditor/Forms/ImageEditorForm.cs @@ -971,6 +971,15 @@ private void hideToolstripItems() /// private void refreshEditorControls() { + int stepLabels = surface.CountStepLabels(null); + if (stepLabels <= 20) + { + //this.btnStepLabel.Image = ((System.Drawing.Image)(resources.GetObject(string.Format("btnStepLabel{0:00}.Image", stepLabels)))); + } + else + { + //this.btnStepLabel.Image = ((System.Drawing.Image)(resources.GetObject("btnStepLabel20+.Image"))); + } FieldAggregator props = surface.FieldAggregator; // if a confirmable element is selected, we must disable most of the controls // since we demand confirmation or cancel for confirmable element diff --git a/GreenshotImageEditor/GreenshotImageEditor.csproj b/GreenshotImageEditor/GreenshotImageEditor.csproj index 2eff601a8..99cc9782a 100644 --- a/GreenshotImageEditor/GreenshotImageEditor.csproj +++ b/GreenshotImageEditor/GreenshotImageEditor.csproj @@ -55,7 +55,6 @@ - diff --git a/GreenshotImageEditor/Properties/AssemblyInfo.cs b/GreenshotImageEditor/Properties/AssemblyInfo.cs index e4e2dbb42..da681200d 100644 --- a/GreenshotImageEditor/Properties/AssemblyInfo.cs +++ b/GreenshotImageEditor/Properties/AssemblyInfo.cs @@ -48,4 +48,4 @@ // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly: AssemblyVersion("1.0.0.2534")] \ No newline at end of file +[assembly: AssemblyVersion("1.2.0.0")] \ No newline at end of file