mirror of
https://github.com/greenshot/greenshot
synced 2025-08-19 04:59:30 -07:00
Some code improvements which make some later features possible (maybe having a bezier for a line) [skip ci]
This commit is contained in:
parent
78cbb055cb
commit
64c77ea8d9
12 changed files with 146 additions and 99 deletions
|
@ -350,7 +350,7 @@ namespace Greenshot.Base.Controls
|
||||||
{
|
{
|
||||||
if (!Language.TryGetString(languageKey, out langString))
|
if (!Language.TryGetString(languageKey, out langString))
|
||||||
{
|
{
|
||||||
LOG.WarnFormat("Unknown language key '{0}' configured for control '{1}', this might be okay.", languageKey, applyTo.Name);
|
LOG.DebugFormat("Unknown language key '{0}' configured for control '{1}', this might be okay.", languageKey, applyTo.Name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -470,7 +470,7 @@ namespace Greenshot.Base.Core
|
||||||
languageFile
|
languageFile
|
||||||
};
|
};
|
||||||
LanguageFiles.Add(languageFile.Ietf, currentFiles);
|
LanguageFiles.Add(languageFile.Ietf, currentFiles);
|
||||||
Log.InfoFormat("Added language definition {0} from: {1}", languageFile.Description, languageFile.Filepath);
|
Log.DebugFormat("Added language definition {0} from: {1}", languageFile.Description, languageFile.Filepath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,5 +108,10 @@ namespace Greenshot.Base.Interfaces.Drawing.Adorners
|
||||||
/// The color of the fill of the adorner
|
/// The color of the fill of the adorner
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Color FillColor { get; set; }
|
Color FillColor { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is to TAG the adorner so we know the type
|
||||||
|
/// </summary>
|
||||||
|
string Tag { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,6 +24,7 @@ using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Windows.Forms;
|
||||||
using Greenshot.Base.Interfaces.Drawing.Adorners;
|
using Greenshot.Base.Interfaces.Drawing.Adorners;
|
||||||
|
|
||||||
namespace Greenshot.Base.Interfaces.Drawing
|
namespace Greenshot.Base.Interfaces.Drawing
|
||||||
|
@ -97,5 +98,13 @@ namespace Greenshot.Base.Interfaces.Drawing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dpi">uint</param>
|
/// <param name="dpi">uint</param>
|
||||||
void AdjustToDpi(uint dpi);
|
void AdjustToDpi(uint dpi);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enable a way for elements to add a context menu entry
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="menu">ContextMenuStrip</param>
|
||||||
|
/// <param name="surface">ISurface</param>
|
||||||
|
/// <param name="mouseEventArgs">MouseEventArgs</param>
|
||||||
|
void AddContextMenuItems(ContextMenuStrip menu, ISurface surface, MouseEventArgs mouseEventArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -101,13 +101,49 @@ namespace Greenshot.Base.Interfaces
|
||||||
long SaveElementsToStream(Stream stream);
|
long SaveElementsToStream(Stream stream);
|
||||||
void LoadElementsFromStream(Stream stream);
|
void LoadElementsFromStream(Stream stream);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides the selected elements
|
||||||
|
/// </summary>
|
||||||
|
IDrawableContainerList SelectedElements { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is there an element selected on the surface?
|
||||||
|
/// </summary>
|
||||||
bool HasSelectedElements { get; }
|
bool HasSelectedElements { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove all selected elements
|
||||||
|
/// </summary>
|
||||||
void RemoveSelectedElements();
|
void RemoveSelectedElements();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cut the selected elements to the clipboard
|
||||||
|
/// </summary>
|
||||||
void CutSelectedElements();
|
void CutSelectedElements();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copy the selected elements to the clipboard
|
||||||
|
/// </summary>
|
||||||
void CopySelectedElements();
|
void CopySelectedElements();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Paste the elements from the clipboard
|
||||||
|
/// </summary>
|
||||||
void PasteElementFromClipboard();
|
void PasteElementFromClipboard();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Duplicate the selected elements
|
||||||
|
/// </summary>
|
||||||
void DuplicateSelectedElements();
|
void DuplicateSelectedElements();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deselected the specified element
|
||||||
|
/// </summary>
|
||||||
void DeselectElement(IDrawableContainer container, bool generateEvents = true);
|
void DeselectElement(IDrawableContainer container, bool generateEvents = true);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deselected all elements
|
||||||
|
/// </summary>
|
||||||
void DeselectAllElements();
|
void DeselectAllElements();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -28,5 +28,7 @@ namespace Greenshot.Base.UnmanagedHelpers.Enums
|
||||||
{
|
{
|
||||||
REGION_ERROR = 0,
|
REGION_ERROR = 0,
|
||||||
REGION_NULLREGION = 1,
|
REGION_NULLREGION = 1,
|
||||||
|
SIMPLEREGION = 2,
|
||||||
|
COMPLEXREGION = 3
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -176,5 +176,10 @@ namespace Greenshot.Editor.Drawing.Adorners
|
||||||
public virtual void Transform(Matrix matrix)
|
public virtual void Transform(Matrix matrix)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is to TAG the adorner so we know the type
|
||||||
|
/// </summary>
|
||||||
|
public string Tag { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,7 +27,7 @@ using Greenshot.Base.Interfaces.Drawing;
|
||||||
namespace Greenshot.Editor.Drawing.Adorners
|
namespace Greenshot.Editor.Drawing.Adorners
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This implements the special "gripper" for the Speech-Bubble tail
|
/// This implements the special target "gripper", e.g. used for the Speech-Bubble tail
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class TargetAdorner : AbstractAdorner
|
public sealed class TargetAdorner : AbstractAdorner
|
||||||
{
|
{
|
||||||
|
@ -41,8 +41,8 @@ namespace Greenshot.Editor.Drawing.Adorners
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handle the mouse down
|
/// Handle the mouse down
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender">object</param>
|
||||||
/// <param name="mouseEventArgs"></param>
|
/// <param name="mouseEventArgs">MouseEventArgs</param>
|
||||||
public override void MouseDown(object sender, MouseEventArgs mouseEventArgs)
|
public override void MouseDown(object sender, MouseEventArgs mouseEventArgs)
|
||||||
{
|
{
|
||||||
EditStatus = EditStatus.MOVING;
|
EditStatus = EditStatus.MOVING;
|
||||||
|
@ -51,8 +51,8 @@ namespace Greenshot.Editor.Drawing.Adorners
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handle the mouse move
|
/// Handle the mouse move
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender">object</param>
|
||||||
/// <param name="mouseEventArgs"></param>
|
/// <param name="mouseEventArgs">MouseEventArgs</param>
|
||||||
public override void MouseMove(object sender, MouseEventArgs mouseEventArgs)
|
public override void MouseMove(object sender, MouseEventArgs mouseEventArgs)
|
||||||
{
|
{
|
||||||
if (EditStatus != EditStatus.MOVING)
|
if (EditStatus != EditStatus.MOVING)
|
||||||
|
|
|
@ -66,44 +66,40 @@ namespace Greenshot.Editor.Drawing
|
||||||
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
|
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
|
||||||
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
||||||
|
|
||||||
if (lineThickness > 0)
|
if (lineThickness <= 0) return;
|
||||||
|
|
||||||
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.None;
|
||||||
|
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
|
||||||
|
ArrowHeadCombination heads = (ArrowHeadCombination) GetFieldValue(FieldType.ARROWHEADS);
|
||||||
|
if (shadow)
|
||||||
{
|
{
|
||||||
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
//draw shadow first
|
||||||
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
int basealpha = 100;
|
||||||
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
int alpha = basealpha;
|
||||||
graphics.PixelOffsetMode = PixelOffsetMode.None;
|
int steps = 5;
|
||||||
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
|
int currentStep = 1;
|
||||||
ArrowHeadCombination heads = (ArrowHeadCombination) GetFieldValue(FieldType.ARROWHEADS);
|
while (currentStep <= steps)
|
||||||
if (lineThickness > 0)
|
|
||||||
{
|
{
|
||||||
if (shadow)
|
using Pen shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness);
|
||||||
{
|
SetArrowHeads(heads, shadowCapPen);
|
||||||
//draw shadow first
|
|
||||||
int basealpha = 100;
|
|
||||||
int alpha = basealpha;
|
|
||||||
int steps = 5;
|
|
||||||
int currentStep = 1;
|
|
||||||
while (currentStep <= steps)
|
|
||||||
{
|
|
||||||
using Pen shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness);
|
|
||||||
SetArrowHeads(heads, shadowCapPen);
|
|
||||||
|
|
||||||
graphics.DrawLine(shadowCapPen,
|
graphics.DrawLine(shadowCapPen,
|
||||||
Left + currentStep,
|
Left + currentStep,
|
||||||
Top + currentStep,
|
Top + currentStep,
|
||||||
Left + currentStep + Width,
|
Left + currentStep + Width,
|
||||||
Top + currentStep + Height);
|
Top + currentStep + Height);
|
||||||
|
|
||||||
currentStep++;
|
currentStep++;
|
||||||
alpha -= basealpha / steps;
|
alpha -= basealpha / steps;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
using Pen pen = new Pen(lineColor, lineThickness);
|
|
||||||
SetArrowHeads(heads, pen);
|
|
||||||
graphics.DrawLine(pen, Left, Top, Left + Width, Top + Height);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using Pen pen = new Pen(lineColor, lineThickness);
|
||||||
|
SetArrowHeads(heads, pen);
|
||||||
|
graphics.DrawLine(pen, Left, Top, Left + Width, Top + Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetArrowHeads(ArrowHeadCombination heads, Pen pen)
|
private void SetArrowHeads(ArrowHeadCombination heads, Pen pen)
|
||||||
|
|
|
@ -26,6 +26,7 @@ using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using System.Windows.Forms;
|
||||||
using Greenshot.Base.IniFile;
|
using Greenshot.Base.IniFile;
|
||||||
using Greenshot.Base.Interfaces;
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
|
@ -448,6 +449,12 @@ namespace Greenshot.Editor.Drawing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IDrawableContainer"/>
|
||||||
|
public virtual void AddContextMenuItems(ContextMenuStrip menu, ISurface surface, MouseEventArgs mouseEventArgs)
|
||||||
|
{
|
||||||
|
// Empty as we do not want to add something to the context menu for every element
|
||||||
|
}
|
||||||
|
|
||||||
public virtual bool Contains(int x, int y)
|
public virtual bool Contains(int x, int y)
|
||||||
{
|
{
|
||||||
return Bounds.Contains(x, y);
|
return Bounds.Contains(x, y);
|
||||||
|
|
|
@ -589,9 +589,10 @@ namespace Greenshot.Editor.Drawing
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add items to a context menu for the selected item
|
/// Add items to a context menu for the selected item
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="menu"></param>
|
/// <param name="menu">ContextMenuStrip</param>
|
||||||
/// <param name="surface"></param>
|
/// <param name="surface">ISurface</param>
|
||||||
public virtual void AddContextMenuItems(ContextMenuStrip menu, ISurface surface)
|
/// <param name="mouseEventArgs">MouseEventArgs</param>
|
||||||
|
public virtual void AddContextMenuItems(ContextMenuStrip menu, ISurface surface, MouseEventArgs mouseEventArgs)
|
||||||
{
|
{
|
||||||
bool push = surface.Elements.CanPushDown(this);
|
bool push = surface.Elements.CanPushDown(this);
|
||||||
bool pull = surface.Elements.CanPullUp(this);
|
bool pull = surface.Elements.CanPullUp(this);
|
||||||
|
@ -678,15 +679,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
menu.Items.Add(item);
|
menu.Items.Add(item);
|
||||||
|
|
||||||
// Reset
|
// Reset
|
||||||
bool canReset = false;
|
bool canReset = this.Cast<DrawableContainer>().Any(container => container.HasDefaultSize);
|
||||||
foreach (var drawableContainer in this)
|
|
||||||
{
|
|
||||||
var container = (DrawableContainer) drawableContainer;
|
|
||||||
if (container.HasDefaultSize)
|
|
||||||
{
|
|
||||||
canReset = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (canReset)
|
if (canReset)
|
||||||
{
|
{
|
||||||
|
@ -713,48 +706,40 @@ namespace Greenshot.Editor.Drawing
|
||||||
};
|
};
|
||||||
menu.Items.Add(item);
|
menu.Items.Add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "ask" the containers to add to the context menu
|
||||||
|
foreach (var surfaceElement in surface.Elements)
|
||||||
|
{
|
||||||
|
surfaceElement.AddContextMenuItems(menu, surface, mouseEventArgs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ShowContextMenu(MouseEventArgs e, ISurface iSurface)
|
public virtual void ShowContextMenu(MouseEventArgs mouseEventArgs, ISurface iSurface)
|
||||||
{
|
{
|
||||||
if (iSurface is not Surface surface)
|
if (iSurface is not Surface surface)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasMenu = false;
|
bool hasMenu = this.Cast<DrawableContainer>().Any(container => container.HasContextMenu);
|
||||||
foreach (var drawableContainer in this)
|
|
||||||
|
if (!hasMenu) return;
|
||||||
|
|
||||||
|
ContextMenuStrip menu = new ContextMenuStrip();
|
||||||
|
AddContextMenuItems(menu, surface, mouseEventArgs);
|
||||||
|
if (menu.Items.Count <= 0) return;
|
||||||
|
menu.Show(surface, surface.ToSurfaceCoordinates(mouseEventArgs.Location));
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
var container = (DrawableContainer) drawableContainer;
|
if (menu.Visible)
|
||||||
if (!container.HasContextMenu)
|
|
||||||
{
|
{
|
||||||
continue;
|
Application.DoEvents();
|
||||||
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
hasMenu = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasMenu)
|
|
||||||
{
|
|
||||||
ContextMenuStrip menu = new ContextMenuStrip();
|
|
||||||
AddContextMenuItems(menu, surface);
|
|
||||||
if (menu.Items.Count > 0)
|
|
||||||
{
|
{
|
||||||
menu.Show(surface, surface.ToSurfaceCoordinates(e.Location));
|
menu.Dispose();
|
||||||
while (true)
|
break;
|
||||||
{
|
|
||||||
if (menu.Visible)
|
|
||||||
{
|
|
||||||
Application.DoEvents();
|
|
||||||
Thread.Sleep(100);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
menu.Dispose();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -763,18 +748,16 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (!_disposedValue)
|
if (_disposedValue) return;
|
||||||
|
if (disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
foreach (var drawableContainer in this)
|
||||||
{
|
{
|
||||||
foreach (var drawableContainer in this)
|
drawableContainer.Dispose();
|
||||||
{
|
|
||||||
drawableContainer.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_disposedValue = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_disposedValue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This code added to correctly implement the disposable pattern.
|
// This code added to correctly implement the disposable pattern.
|
||||||
|
|
|
@ -2036,23 +2036,27 @@ namespace Greenshot.Editor.Drawing
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns if this surface has selected elements
|
/// Returns if this surface has selected elements
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns>bool</returns>
|
||||||
public bool HasSelectedElements => (selectedElements != null && selectedElements.Count > 0);
|
public bool HasSelectedElements => selectedElements is { Count: > 0 };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides the selected elements
|
||||||
|
/// </summary>
|
||||||
|
public IDrawableContainerList SelectedElements => selectedElements;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove all the selected elements
|
/// Remove all the selected elements
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void RemoveSelectedElements()
|
public void RemoveSelectedElements()
|
||||||
{
|
{
|
||||||
if (HasSelectedElements)
|
if (!HasSelectedElements) return;
|
||||||
|
|
||||||
|
// As RemoveElement will remove the element from the selectedElements list we need to copy the element to another list.
|
||||||
|
RemoveElements(selectedElements);
|
||||||
|
if (_movingElementChanged != null)
|
||||||
{
|
{
|
||||||
// As RemoveElement will remove the element from the selectedElements list we need to copy the element to another list.
|
SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
|
||||||
RemoveElements(selectedElements);
|
_movingElementChanged(this, eventArgs);
|
||||||
if (_movingElementChanged != null)
|
|
||||||
{
|
|
||||||
SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
|
|
||||||
_movingElementChanged(this, eventArgs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue