Trying to replace the Gripper (which is a Label/Control) with adorners (custom code). This should prevent the slow cleanup, reduce resources and speedup the editor. Also we should have better "UI" feedback. This is still very experimental.

This commit is contained in:
Robin 2016-05-23 13:32:52 +02:00
parent e9ab99c5ac
commit 31db071394
15 changed files with 643 additions and 349 deletions

View file

@ -21,12 +21,14 @@
using Greenshot.Configuration;
using Greenshot.Core;
using Greenshot.Drawing.Adorners;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.IniFile;
using Greenshot.Memento;
using Greenshot.Plugin;
using Greenshot.Plugin.Drawing;
using Greenshot.Plugin.Drawing.Adorners;
using GreenshotPlugin.Controls;
using GreenshotPlugin.Core;
using log4net;
@ -991,12 +993,45 @@ namespace Greenshot.Drawing {
Invalidate();
}
/// <summary>
/// Check if an adorner was "hit", and change the cursor if so
/// </summary>
/// <param name="mouseEventArgs">MouseEventArgs</param>
/// <returns>IAdorner</returns>
private IAdorner AdornersHitTest(MouseEventArgs mouseEventArgs)
{
foreach(IDrawableContainer drawableContainer in selectedElements)
{
foreach(IAdorner adorner in drawableContainer.Adorners)
{
if (adorner.HitTest(mouseEventArgs.Location))
{
if (adorner.Cursor != null)
{
Cursor = adorner.Cursor;
}
return adorner;
}
}
}
return null;
}
/// <summary>
/// This event handler is called when someone presses the mouse on a surface.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void SurfaceMouseDown(object sender, MouseEventArgs e) {
// Handle Adorners
var adorner = AdornersHitTest(e);
if (adorner != null)
{
adorner.MouseDown(sender, e);
return;
}
_mouseStart = e.Location;
// check contextmenu
@ -1065,6 +1100,15 @@ namespace Greenshot.Drawing {
/// <param name="sender"></param>
/// <param name="e"></param>
void SurfaceMouseUp(object sender, MouseEventArgs e) {
// Handle Adorners
var adorner = AdornersHitTest(e);
if (adorner != null)
{
adorner.MouseUp(sender, e);
return;
}
Point currentMouse = new Point(e.X, e.Y);
_elements.Status = EditStatus.IDLE;
@ -1098,7 +1142,7 @@ namespace Greenshot.Drawing {
}
if (selectedElements.Count > 0) {
selectedElements.ShowGrippers();
selectedElements.Invalidate();
selectedElements.Selected = true;
}
@ -1126,6 +1170,14 @@ namespace Greenshot.Drawing {
/// <param name="sender"></param>
/// <param name="e"></param>
void SurfaceMouseMove(object sender, MouseEventArgs e) {
// Handle Adorners
var adorner = AdornersHitTest(e);
if (adorner != null)
{
adorner.MouseMove(sender, e);
return;
}
Point currentMouse = e.Location;
if (DrawingMode != DrawingModes.None) {
@ -1137,7 +1189,7 @@ namespace Greenshot.Drawing {
if (_mouseDown) {
if (_mouseDownElement != null) { // an element is currently dragged
_mouseDownElement.Invalidate();
selectedElements.HideGrippers();
selectedElements.Invalidate();
// Move the element
if (_mouseDownElement.Selected) {
if (!_isSurfaceMoveMadeUndoable) {
@ -1203,15 +1255,15 @@ namespace Greenshot.Drawing {
public Image GetImageForExport() {
return GetImage(RenderMode.EXPORT);
}
/// <summary>
/// This is the event handler for the Paint Event, try to draw as little as possible!
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void SurfacePaint(object sender, PaintEventArgs e) {
Graphics targetGraphics = e.Graphics;
Rectangle clipRectangle = e.ClipRectangle;
/// <param name="paintEventArgs">PaintEventArgs</param>
void SurfacePaint(object sender, PaintEventArgs paintEventArgs) {
Graphics targetGraphics = paintEventArgs.Graphics;
Rectangle clipRectangle = paintEventArgs.ClipRectangle;
if (Rectangle.Empty.Equals(clipRectangle)) {
LOG.Debug("Empty cliprectangle??");
return;
@ -1246,6 +1298,15 @@ namespace Greenshot.Drawing {
targetGraphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
_elements.Draw(targetGraphics, null, RenderMode.EDIT, clipRectangle);
}
// Draw adorners last
foreach(var drawableContainer in selectedElements)
{
foreach(var adorner in drawableContainer.Adorners)
{
adorner.Paint(paintEventArgs);
}
}
}
private void DrawBackground(Graphics targetGraphics, Rectangle clipRectangle) {
@ -1531,9 +1592,9 @@ namespace Greenshot.Drawing {
/// </summary>
/// <param name="container"></param>
public void DeselectElement(IDrawableContainer container) {
container.HideGrippers();
container.Selected = false;
selectedElements.Remove(container);
container.Invalidate();
FieldAggregator.UnbindElement(container);
if (_movingElementChanged != null) {
SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
@ -1549,10 +1610,9 @@ namespace Greenshot.Drawing {
if (HasSelectedElements) {
while(selectedElements.Count > 0) {
IDrawableContainer element = selectedElements[0];
element.Invalidate();
element.HideGrippers();
element.Selected = false;
selectedElements.Remove(element);
element.Invalidate();
FieldAggregator.UnbindElement(element);
}
if (_movingElementChanged != null) {
@ -1570,7 +1630,6 @@ namespace Greenshot.Drawing {
public void SelectElement(IDrawableContainer container) {
if (!selectedElements.Contains(container)) {
selectedElements.Add(container);
container.ShowGrippers();
container.Selected = true;
FieldAggregator.BindElement(container);
if (_movingElementChanged != null) {