Blame mono/Assistance/ToolFull.cs

b9e5e0
using System;
b9e5e0
using System.Collections.Generic;
b9e5e0
b9e5e0
namespace Assistance {
b9e5e0
	public class ToolFull: Tool {
b9e5e0
		public static readonly Drawing.Pen pen = new Drawing.Pen("Dark Green", 10.0);
b9e5e0
		public static readonly double levelAlpha = 0.8;
b9e5e0
	
b9e5e0
		
b9e5e0
		private readonly List<dynamicsurface> stack = new List<dynamicsurface>();</dynamicsurface></dynamicsurface>
b9e5e0
b9e5e0
		
b9e5e0
		public ToolFull(Workarea workarea): base(workarea) { }
b9e5e0
		
b9e5e0
		public override ModifierTypes getAvailableModifierTypes()
b9e5e0
			{ return ModifierTypes.All; }
b9e5e0
		
b9e5e0
		private DynamicSurface getSurface(int level)
b9e5e0
			{ return level > 0 ? stack[level - 1] : workarea.document.canvas; }
b9e5e0
		private DynamicSurface getSurface()
b9e5e0
			{ return getSurface(stack.Count); }
b9e5e0
		
b9e5e0
		public override bool paintPush() {
b9e5e0
			stack.Add(new DynamicSurface());
b9e5e0
			return true;
b9e5e0
		}
b9e5e0
b9e5e0
		private void paintPoint(DynamicSurface surface, Cairo.Context context, Track.WayPoint point) {
b9e5e0
			Point p = point.point.position;
b9e5e0
			double r = pen.width*point.point.pressure;
b9e5e0
			double rr = r + 1.0;
b9e5e0
			
b9e5e0
			surface.expandContext(ref context, new Rectangle(p.x - rr, p.y - rr, p.x + rr, p.y + rr));
b9e5e0
b9e5e0
			context.Save();
b9e5e0
			pen.apply(context);
b9e5e0
			context.Arc(p.x, p.y, r, 0.0, 2.0*Math.PI);
b9e5e0
			context.Fill();
b9e5e0
			context.Restore();
b9e5e0
		}
b9e5e0
b9e5e0
		public override void paintTracks(List<track> tracks) {
b9e5e0
			DynamicSurface surface = getSurface();
b9e5e0
			Cairo.Context context = surface.getContext();
b9e5e0
			while(true) {
b9e5e0
				Track track = null;
b9e5e0
				long minTicks = long.MaxValue;
b9e5e0
				double minTimeOffset = 0.0;
b9e5e0
				foreach(Track t in tracks) {
b9e5e0
					if (t.wayPointsAdded > 0) {
b9e5e0
						long ticks = t.ticks;
b9e5e0
						double timeOffset = t.timeOffset + t.points[t.points.Count - t.wayPointsAdded].time;
b9e5e0
						if ((ticks - minTicks)*Timer.frequency + timeOffset - minTimeOffset < 0.0) {
b9e5e0
							track = t;
b9e5e0
							minTicks = ticks;
b9e5e0
							minTimeOffset = timeOffset;
b9e5e0
						}
b9e5e0
					}
b9e5e0
				}
b9e5e0
				if (track == null) break;
b9e5e0
				paintPoint(surface, context, track.points[track.points.Count - track.wayPointsAdded]);
b9e5e0
				--track.wayPointsAdded;
b9e5e0
			}
b9e5e0
			context.GetTarget().Flush();
b9e5e0
			context.Dispose();
b9e5e0
		}
b9e5e0
		
b9e5e0
		public override int paintApply(int count) {
b9e5e0
			int level = stack.Count - count;
b9e5e0
			DynamicSurface surface = getSurface(level);
b9e5e0
			Cairo.Context context = surface.getContext();
b9e5e0
			for(int i = level; i < stack.Count; ++i) {
b9e5e0
				surface.expandContext(ref context, stack[i].getBounds(), true);
b9e5e0
				stack[i].draw(context);
b9e5e0
			}
b9e5e0
			context.GetTarget().Flush();
b9e5e0
			context.Dispose();
b9e5e0
			paintPop(count);
b9e5e0
			return count;
b9e5e0
		}
b9e5e0
		
b9e5e0
		public override void paintCancel()
b9e5e0
			{ getSurface().clear(); }
b9e5e0
		
b9e5e0
		public override void paintPop(int count) {
b9e5e0
			int level = stack.Count - count;
b9e5e0
			for(int i = stack.Count - 1; i >= level; --i)
b9e5e0
				stack[i].Dispose();
b9e5e0
			stack.RemoveRange(level, count);
b9e5e0
		}
b9e5e0
b9e5e0
		public override void draw(Cairo.Context context) {
b9e5e0
			double alpha = levelAlpha;
b9e5e0
			foreach(DynamicSurface surface in stack)
b9e5e0
				{ surface.draw(context, alpha); alpha *= levelAlpha; }
b9e5e0
		}
b9e5e0
	}
b9e5e0
}