|
|
b9e5e0 |
using System;
|
|
|
b9e5e0 |
using System.Collections.Generic;
|
|
|
b9e5e0 |
|
|
|
b9e5e0 |
namespace Assistance {
|
|
|
b9e5e0 |
public class ToolFull: Tool {
|
|
|
0f2bf8 |
public static readonly Drawing.Pen pen = new Drawing.Pen("Dark Green", 3.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 |
|
|
|
702257 |
private void paintPoint(DynamicSurface surface, Track.Point point) {
|
|
|
702257 |
Point p = point.position;
|
|
|
702257 |
double r = pen.width*point.pressure;
|
|
|
0f2bf8 |
Drawing.Color color = pen.color;
|
|
|
0f2bf8 |
if (r < 0.01) r = 0.01;
|
|
|
0f2bf8 |
if (r > Geometry.precision && r < 0.5)
|
|
|
0f2bf8 |
{ color.a *= r/0.5; r = 0.5; }
|
|
|
b9e5e0 |
double rr = r + 1.0;
|
|
|
b9e5e0 |
|
|
|
0f2bf8 |
surface.expand(new Rectangle(p.x - rr, p.y - rr, p.x + rr, p.y + rr));
|
|
|
b9e5e0 |
|
|
|
0f2bf8 |
surface.context.Save();
|
|
|
0f2bf8 |
pen.apply(surface.context);
|
|
|
0f2bf8 |
color.apply(surface.context);
|
|
|
0f2bf8 |
surface.context.Arc(p.x, p.y, r, 0.0, 2.0*Math.PI);
|
|
|
0f2bf8 |
surface.context.Fill();
|
|
|
7bbf70 |
|
|
|
0f2bf8 |
surface.context.Restore();
|
|
|
b9e5e0 |
}
|
|
|
b9e5e0 |
|
|
|
b9e5e0 |
public override void paintTracks(List<track> tracks) {
|
|
|
b9e5e0 |
DynamicSurface surface = getSurface();
|
|
|
b9e5e0 |
while(true) {
|
|
|
b9e5e0 |
Track track = null;
|
|
|
0f2bf8 |
long minTicks = 0;
|
|
|
b9e5e0 |
double minTimeOffset = 0.0;
|
|
|
b9e5e0 |
foreach(Track t in tracks) {
|
|
|
72d2fd |
if (t.pointsAdded > 0) {
|
|
|
b9e5e0 |
long ticks = t.ticks;
|
|
|
72d2fd |
double timeOffset = t.timeOffset + t[t.count - t.pointsAdded].time;
|
|
|
0f2bf8 |
if (track == null || (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;
|
|
|
72d2fd |
paintPoint(surface, track[track.count - track.pointsAdded]);
|
|
|
72d2fd |
track.forceAdded(track.pointsAdded - 1);
|
|
|
b9e5e0 |
}
|
|
|
b9e5e0 |
}
|
|
|
b9e5e0 |
|
|
|
b9e5e0 |
public override int paintApply(int count) {
|
|
|
b9e5e0 |
int level = stack.Count - count;
|
|
|
b9e5e0 |
DynamicSurface surface = getSurface(level);
|
|
|
b9e5e0 |
for(int i = level; i < stack.Count; ++i) {
|
|
|
0f2bf8 |
surface.expand(stack[i].getBounds(), true);
|
|
|
0f2bf8 |
stack[i].draw(surface.context);
|
|
|
b9e5e0 |
}
|
|
|
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 |
}
|