123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- using PaintDotNet.Measurement.HistoryMementos;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Windows.Forms;
- namespace PaintDotNet.Measurement.Tools
- {
- public class PencilTool : Tool
- {
- private bool mouseDown = false;
- private ColorBgra pencilColor;
- private MouseButtons mouseButton;
- private BitmapLayer bitmapLayer;
- private RenderArgs renderArgs;
- private List<Point> tracePoints;
- private List<Rectangle> savedRects;
- private PdnRegion clipRegion;
- private Point lastPoint;
- private Point difference;
- private Cursor pencilToolCursor;
- private BinaryPixelOp blendOp = new UserBlendOps.NormalBlendOp();
- private BinaryPixelOp copyOp = new BinaryPixelOps.AssignFromRhs();
- protected override void OnActivate()
- {
- base.OnActivate();
- this.pencilToolCursor = new Cursor(PdnResources.GetResourceStream("Cursors.PencilToolCursor.cur"));
- this.Cursor = this.pencilToolCursor;
- this.savedRects = new List<Rectangle>();
- if (ActiveLayer != null)
- {
- bitmapLayer = (BitmapLayer)ActiveLayer;
- renderArgs = new RenderArgs(bitmapLayer.Surface);
- tracePoints = new List<Point>();
- }
- else
- {
- bitmapLayer = null;
- if (renderArgs != null)
- {
- renderArgs.Dispose();
- renderArgs = null;
- }
- }
- }
- protected override void OnDeactivate()
- {
- base.OnDeactivate();
- if (this.pencilToolCursor != null)
- {
- this.pencilToolCursor.Dispose();
- this.pencilToolCursor = null;
- }
- if (mouseDown)
- {
- Point lastTracePoint = (Point)tracePoints[tracePoints.Count - 1];
- OnMouseUp(new MouseEventArgs(mouseButton, 0, lastTracePoint.X, lastTracePoint.Y, 0));
- }
- this.savedRects = null;
- this.tracePoints = null;
- this.bitmapLayer = null;
- if (this.renderArgs != null)
- {
- this.renderArgs.Dispose();
- this.renderArgs = null;
- }
- this.mouseDown = false;
- if (clipRegion != null)
- {
- clipRegion.Dispose();
- clipRegion = null;
- }
- }
- // Draws a point, but first intersects it with the selection
- private void DrawPoint(RenderArgs ra, Point p, ColorBgra color)
- {
- if (ra.Surface.Bounds.Contains(p))
- {
- if (ra.Graphics.IsVisible(p))
- {
- BinaryPixelOp op = AppEnvironment.AlphaBlending() ? blendOp : copyOp;
- ra.Surface[p.X, p.Y] = op.Apply(ra.Surface[p.X, p.Y], color);
- }
- }
- }
- private void DrawLines(RenderArgs ra, List<Point> points, int startIndex, int length, ColorBgra color)
- {
- // Draw a point in the line
- if (points.Count == 0)
- {
- return;
- }
- else if (points.Count == 1)
- {
- Point p = (Point)points[0];
- if (ra.Surface.Bounds.Contains(p))
- {
- DrawPoint(ra, p, color);
- }
- }
- else
- {
- for (int i = startIndex + 1; i < startIndex + length; ++i)
- {
- Point[] linePoints = Utility.GetLinePoints(points[i - 1], points[i]);
- int startPoint = 0;
- if (i != 1)
- {
- startPoint = 1;
- }
- for (int pi = startPoint; pi < linePoints.Length; ++pi)
- {
- Point p = linePoints[pi];
- DrawPoint(ra, p, color);
- }
- }
- }
- }
- protected override void OnMouseDown(MouseEventArgs e)
- {
- base.OnMouseDown(e);
- if (mouseDown)
- {
- return;
- }
- if (((e.Button & MouseButtons.Left) == MouseButtons.Left) ||
- ((e.Button & MouseButtons.Right) == MouseButtons.Right))
- {
- mouseDown = true;
- mouseButton = e.Button;
- tracePoints = new List<Point>();
- bitmapLayer = (BitmapLayer)ActiveLayer;
- renderArgs = new RenderArgs(bitmapLayer.Surface);
- if (clipRegion != null)
- {
- clipRegion.Dispose();
- clipRegion = null;
- }
- clipRegion = Selection.CreateRegion();
- renderArgs.Graphics.SetClip(clipRegion.GetRegionReadOnly(), CombineMode.Replace);
- OnMouseMove(e);
- }
- }
- protected override void OnMouseMove(MouseEventArgs e)
- {
- base.OnMouseMove(e);
- if (mouseDown && ((e.Button & mouseButton) != MouseButtons.None))
- {
- Point mouseXY = new Point(e.X, e.Y);
- if (lastPoint == Point.Empty)
- {
- lastPoint = mouseXY;
- }
- difference = new Point(mouseXY.X - lastPoint.X, mouseXY.Y - lastPoint.Y);
- if (tracePoints.Count > 0)
- {
- Point lastMouseXY = (Point)tracePoints[tracePoints.Count - 1];
- if (lastMouseXY == mouseXY)
- {
- return;
- }
- }
- if ((mouseButton & MouseButtons.Left) == MouseButtons.Left)
- {
- this.pencilColor = AppEnvironment.PrimaryColor();
- }
- else // if ((mouseButton & MouseButtons.Right) == MouseButtons.Right)
- {
- // right mouse button = swap primary/secondary
- this.pencilColor = AppEnvironment.SecondaryColor();
- }
- if (!(tracePoints.Count > 0 && mouseXY == (Point)tracePoints[tracePoints.Count - 1]))
- {
- tracePoints.Add(mouseXY);
- }
- if (ActiveLayer is BitmapLayer)
- {
- Rectangle saveRect;
- if (tracePoints.Count == 1)
- {
- saveRect = Utility.PointsToRectangle(mouseXY, mouseXY);
- }
- else
- {
- // >1 points
- saveRect = Utility.PointsToRectangle((Point)tracePoints[tracePoints.Count - 1], (Point)tracePoints[tracePoints.Count - 2]);
- }
- saveRect.Inflate(2, 2);
- saveRect.Intersect(ActiveLayer.Bounds);
- // drawing outside of the canvas is a no-op, so don't do anything in that case!
- // also make sure it's within the clipping bounds
- if (saveRect.Width > 0 && saveRect.Height > 0 && renderArgs.Graphics.IsVisible(saveRect))
- {
- SaveRegion(null, saveRect);
- this.savedRects.Add(saveRect);
- int startIndex;
- int length;
- if (tracePoints.Count == 1)
- {
- startIndex = 0;
- length = 1;
- }
- else
- {
- startIndex = tracePoints.Count - 2;
- length = 2;
- }
- DrawLines(this.renderArgs, tracePoints, startIndex, length, pencilColor);
- bitmapLayer.Invalidate(saveRect);
- Update();
- }
- }
- else
- {
- // will have to do something here if we add other layer types besides BitmapLayer
- }
- lastPoint = mouseXY;
- }
- }
- protected override void OnMouseUp(MouseEventArgs e)
- {
- base.OnMouseUp(e);
- if (mouseDown)
- {
- OnMouseMove(e);
- mouseDown = false;
- if (savedRects.Count > 0)
- {
- Rectangle[] savedScans = this.savedRects.ToArray();
- PdnRegion saveMeRegion = Utility.RectanglesToRegion(savedScans);
- HistoryMemento ha = new BitmapHistoryMemento(Name, Image, DocumentWorkspace,
- ActiveLayerIndex, saveMeRegion, ScratchSurface);
- //HistoryStack.PushNewMemento(ha);
- saveMeRegion.Dispose();
- this.savedRects.Clear();
- ClearSavedMemory();
- }
- tracePoints = null;
- }
- }
- public PencilTool(IDocumentWorkspace documentWorkspace)
- : base(documentWorkspace,
- PdnResources.GetImageResource("Icons.PencilToolIcon.png"),
- PdnResources.GetString("PencilTool.Name"),
- PdnResources.GetString("PencilTool.HelpText"),
- 'p',
- true,
- ToolBarConfigItems.AlphaBlending)
- {
- // initialize any state information you need
- mouseDown = false;
- }
- }
- }
|