|
|
ebcc4f |
using System;
|
|
|
ebcc4f |
using System.Collections.Generic;
|
|
|
ebcc4f |
|
|
|
ebcc4f |
namespace Assistance {
|
|
|
b82ef4 |
public class MainWindow : Gtk.Window {
|
|
|
b82ef4 |
static public void Main() {
|
|
|
b82ef4 |
Gtk.Application.Init();
|
|
|
b82ef4 |
MainWindow win = new MainWindow();
|
|
|
6148f0 |
win.Show();
|
|
|
6148f0 |
win.Maximize();
|
|
|
b82ef4 |
Gtk.Application.Run();
|
|
|
b82ef4 |
}
|
|
|
0f2bf8 |
|
|
|
b1ff53 |
Workarea workarea = new Workarea();
|
|
|
b9e5e0 |
ToolFull toolFull;
|
|
|
b9e5e0 |
|
|
|
ebcc4f |
bool dragging = false;
|
|
|
b9e5e0 |
bool painting = false;
|
|
|
ebcc4f |
ActivePoint activePoint;
|
|
|
b82ef4 |
|
|
|
ebcc4f |
Point offset;
|
|
|
ebcc4f |
Point cursor;
|
|
|
0f2bf8 |
List<point> hovers = new List<point>();</point></point>
|
|
|
b1ff53 |
|
|
|
b9e5e0 |
long touchId;
|
|
|
b9e5e0 |
long ticksStart = 0;
|
|
|
b9e5e0 |
double timeStart = 0;
|
|
|
c66393 |
|
|
|
b82ef4 |
public MainWindow(): base(Gtk.WindowType.Toplevel) {
|
|
|
6148f0 |
foreach(Gdk.Device device in Display.ListDevices()) {
|
|
|
6148f0 |
if (device.Name.Contains("tylus")) {
|
|
|
6148f0 |
device.SetMode(Gdk.InputMode.Screen);
|
|
|
6148f0 |
break;
|
|
|
6148f0 |
}
|
|
|
6148f0 |
}
|
|
|
6148f0 |
|
|
|
6148f0 |
Events = Gdk.EventMask.KeyPressMask
|
|
|
6148f0 |
| Gdk.EventMask.KeyReleaseMask
|
|
|
6148f0 |
| Gdk.EventMask.ButtonPressMask
|
|
|
6148f0 |
| Gdk.EventMask.ButtonReleaseMask
|
|
|
6148f0 |
| Gdk.EventMask.ButtonMotionMask
|
|
|
6148f0 |
| Gdk.EventMask.PointerMotionMask;
|
|
|
6148f0 |
ExtensionEvents = Gdk.ExtensionMode.All;
|
|
|
b9e5e0 |
|
|
|
b9e5e0 |
toolFull = new ToolFull(workarea);
|
|
|
b9e5e0 |
workarea.setTool(toolFull);
|
|
|
ebcc4f |
}
|
|
|
b82ef4 |
|
|
|
0f2bf8 |
private bool refreshOnIdle()
|
|
|
0f2bf8 |
{ QueueDraw(); return false; }
|
|
|
ed66f8 |
private void Refresh() {
|
|
|
ed66f8 |
QueueDraw(); //GLib.Idle.Add(refreshOnIdle);
|
|
|
ed66f8 |
}
|
|
|
0f2bf8 |
|
|
|
b82ef4 |
protected override bool OnDeleteEvent(Gdk.Event e) {
|
|
|
b82ef4 |
Gtk.Application.Quit();
|
|
|
0f2bf8 |
return false;
|
|
|
b82ef4 |
}
|
|
|
ebcc4f |
|
|
|
b82ef4 |
protected override bool OnExposeEvent(Gdk.EventExpose e) {
|
|
|
ed66f8 |
workarea.inputManager.processTracks();
|
|
|
ed66f8 |
|
|
|
0f2bf8 |
Cairo.Context context = Gdk.CairoHelper.Create(e.Window);
|
|
|
0f2bf8 |
|
|
|
b82ef4 |
context.Save();
|
|
|
b82ef4 |
context.SetSourceRGBA(1.0, 1.0, 1.0, 1.0);
|
|
|
0f2bf8 |
context.Rectangle(0, 0, Allocation.Width, Allocation.Height);
|
|
|
b82ef4 |
context.Fill();
|
|
|
b82ef4 |
context.Restore();
|
|
|
0f2bf8 |
|
|
|
0f2bf8 |
context.Save();
|
|
|
0f2bf8 |
context.Antialias = Cairo.Antialias.Gray;
|
|
|
b82ef4 |
draw(context);
|
|
|
0f2bf8 |
context.Restore();
|
|
|
b82ef4 |
|
|
|
b82ef4 |
context.Dispose();
|
|
|
0f2bf8 |
|
|
|
0f2bf8 |
return false;
|
|
|
b82ef4 |
}
|
|
|
ebcc4f |
|
|
|
ed66f8 |
public Point windowToWorkarea(Point p)
|
|
|
ed66f8 |
{ return new Point(p.x - Allocation.Width/2.0, p.y - Allocation.Height/2.0); }
|
|
|
ebcc4f |
|
|
|
ed66f8 |
public Point workareaToWindow(Point p)
|
|
|
ed66f8 |
{ return new Point(p.x + Allocation.Width/2.0, p.y + Allocation.Height/2.0); }
|
|
|
ebcc4f |
|
|
|
ebcc4f |
private void beginDrag() {
|
|
|
b1ff53 |
endDragAndTrack();
|
|
|
ebcc4f |
dragging = true;
|
|
|
ebcc4f |
offset = activePoint.position - cursor;
|
|
|
ebcc4f |
activePoint.bringToFront();
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
|
|
|
b9e5e0 |
private void beginTrack(double timeStart) {
|
|
|
b1ff53 |
endDragAndTrack();
|
|
|
b9e5e0 |
++touchId;
|
|
|
c66393 |
ticksStart = Timer.ticks();
|
|
|
b9e5e0 |
this.timeStart = timeStart;
|
|
|
0f2bf8 |
painting = true;
|
|
|
b1ff53 |
}
|
|
|
b1ff53 |
|
|
|
b1ff53 |
private void endDragAndTrack() {
|
|
|
ebcc4f |
dragging = false;
|
|
|
ebcc4f |
offset = new Point();
|
|
|
b9e5e0 |
if (painting) {
|
|
|
b9e5e0 |
painting = false;
|
|
|
b9e5e0 |
workarea.inputManager.finishTracks();
|
|
|
b9e5e0 |
}
|
|
|
ebcc4f |
}
|
|
|
b82ef4 |
|
|
|
b82ef4 |
protected override bool OnKeyPressEvent(Gdk.EventKey e) {
|
|
|
b82ef4 |
switch(e.Key) {
|
|
|
b82ef4 |
case Gdk.Key.Key_1:
|
|
|
726e8a |
new AssistantVanishingPoint(workarea.document, cursor);
|
|
|
c66393 |
endDragAndTrack();
|
|
|
ebcc4f |
break;
|
|
|
b82ef4 |
case Gdk.Key.Q:
|
|
|
b82ef4 |
case Gdk.Key.q:
|
|
|
726e8a |
new ModifierSnowflake(workarea.document, cursor);
|
|
|
c66393 |
endDragAndTrack();
|
|
|
72b17c |
break;
|
|
|
1cdf17 |
case Gdk.Key.W:
|
|
|
1cdf17 |
case Gdk.Key.w:
|
|
|
1cdf17 |
new ModifierSpiro(workarea.document, cursor);
|
|
|
1cdf17 |
endDragAndTrack();
|
|
|
1cdf17 |
break;
|
|
|
6148f0 |
case Gdk.Key.I:
|
|
|
6148f0 |
case Gdk.Key.i:
|
|
|
6148f0 |
Gtk.InputDialog dialog = new Gtk.InputDialog();
|
|
|
6148f0 |
dialog.CloseButton.Clicked += (object sender, EventArgs args) => { dialog.Destroy(); };
|
|
|
6148f0 |
dialog.Show();
|
|
|
6148f0 |
break;
|
|
|
b82ef4 |
case Gdk.Key.Delete:
|
|
|
ebcc4f |
if (activePoint != null)
|
|
|
72b17c |
activePoint.owner.remove();
|
|
|
b1ff53 |
endDragAndTrack();
|
|
|
ebcc4f |
break;
|
|
|
c66393 |
default:
|
|
|
b9e5e0 |
workarea.inputManager.keyEvent(true, e.Key, Timer.ticks());
|
|
|
c66393 |
break;
|
|
|
ebcc4f |
}
|
|
|
0f2bf8 |
Refresh();
|
|
|
b82ef4 |
return base.OnKeyPressEvent(e);
|
|
|
b82ef4 |
}
|
|
|
b82ef4 |
|
|
|
c66393 |
protected override bool OnKeyReleaseEvent(Gdk.EventKey e) {
|
|
|
b9e5e0 |
workarea.inputManager.keyEvent(false, e.Key, Timer.ticks());
|
|
|
c66393 |
return base.OnKeyReleaseEvent(e);
|
|
|
c66393 |
}
|
|
|
c66393 |
|
|
|
b9e5e0 |
void addTrackPoint(Gdk.Device device, Point p, double time, double pressure, Point tilt, bool final) {
|
|
|
702257 |
if (!painting) return;
|
|
|
b9e5e0 |
long ticks = ticksStart + (long)Math.Round((time - timeStart)*Timer.frequency);
|
|
|
702257 |
workarea.inputManager.trackEvent(device, touchId, p, pressure, tilt, final, ticks);
|
|
|
c66393 |
}
|
|
|
c66393 |
|
|
|
b9e5e0 |
void addTrackPoint(double x, double y, uint t, Gdk.Device device, double[] axes, bool final) {
|
|
|
c66393 |
Point point = windowToWorkarea(new Point(x, y));
|
|
|
0f2bf8 |
double time = (double)t*0.001;
|
|
|
c66393 |
double pressure = 0.5;
|
|
|
c66393 |
Point tilt = new Point(0.0, 0.0);
|
|
|
b82ef4 |
if (device != null && axes != null) {
|
|
|
b82ef4 |
double v;
|
|
|
b82ef4 |
if (device.GetAxis(axes, Gdk.AxisUse.Pressure, out v))
|
|
|
c66393 |
pressure = v;
|
|
|
b82ef4 |
if (device.GetAxis(axes, Gdk.AxisUse.Xtilt, out v))
|
|
|
c66393 |
tilt.x = v;
|
|
|
b82ef4 |
if (device.GetAxis(axes, Gdk.AxisUse.Ytilt, out v))
|
|
|
c66393 |
tilt.y = v;
|
|
|
b82ef4 |
}
|
|
|
b9e5e0 |
addTrackPoint(device, point, time, pressure, tilt, final);
|
|
|
c66393 |
}
|
|
|
c66393 |
|
|
|
b9e5e0 |
void addTrackPoint(Gdk.EventButton e, bool press)
|
|
|
b9e5e0 |
{ addTrackPoint(e.X, e.Y, e.Time, e.Device, e.Axes, !press); }
|
|
|
b9e5e0 |
void addTrackPoint(Gdk.EventMotion e)
|
|
|
b9e5e0 |
{ addTrackPoint(e.X, e.Y, e.Time, e.Device, e.Axes, false); }
|
|
|
b82ef4 |
|
|
|
b82ef4 |
protected override bool OnButtonPressEvent(Gdk.EventButton e) {
|
|
|
b82ef4 |
cursor = windowToWorkarea(new Point(e.X, e.Y));
|
|
|
b9e5e0 |
workarea.inputManager.buttonEvent(true, e.Device, e.Button, Timer.ticks());
|
|
|
b82ef4 |
if (e.Button == 1) {
|
|
|
b1ff53 |
activePoint = workarea.findPoint(cursor);
|
|
|
b1ff53 |
if (activePoint != null) {
|
|
|
ebcc4f |
beginDrag();
|
|
|
b1ff53 |
} else {
|
|
|
b9e5e0 |
beginTrack((double)e.Time*0.001);
|
|
|
b9e5e0 |
addTrackPoint(e, true);
|
|
|
b1ff53 |
}
|
|
|
ebcc4f |
}
|
|
|
0f2bf8 |
Refresh();
|
|
|
0f2bf8 |
return false;
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
|
|
|
b82ef4 |
protected override bool OnButtonReleaseEvent(Gdk.EventButton e) {
|
|
|
b1ff53 |
cursor = windowToWorkarea(new Point(e.X, e.Y));
|
|
|
b9e5e0 |
workarea.inputManager.buttonEvent(false, e.Device, e.Button, Timer.ticks());
|
|
|
b82ef4 |
if (e.Button == 1) {
|
|
|
b9e5e0 |
if (!dragging && painting)
|
|
|
b9e5e0 |
addTrackPoint(e, false);
|
|
|
b1ff53 |
endDragAndTrack();
|
|
|
b9e5e0 |
if (!dragging && !painting)
|
|
|
b82ef4 |
activePoint = workarea.findPoint(cursor);
|
|
|
b82ef4 |
}
|
|
|
0f2bf8 |
Refresh();
|
|
|
0f2bf8 |
return false;
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
|
|
|
b82ef4 |
protected override bool OnMotionNotifyEvent(Gdk.EventMotion e) {
|
|
|
b82ef4 |
cursor = windowToWorkarea(new Point(e.X, e.Y));
|
|
|
ebcc4f |
if (dragging) {
|
|
|
72b17c |
activePoint.owner.onMovePoint(activePoint, cursor + offset);
|
|
|
b1ff53 |
} else
|
|
|
b9e5e0 |
if (painting) {
|
|
|
c66393 |
addTrackPoint(e);
|
|
|
ebcc4f |
} else {
|
|
|
b1ff53 |
activePoint = workarea.findPoint(cursor);
|
|
|
ebcc4f |
}
|
|
|
0f2bf8 |
Refresh();
|
|
|
0f2bf8 |
return false;
|
|
|
b82ef4 |
}
|
|
|
ebcc4f |
|
|
|
b82ef4 |
public void draw(Cairo.Context context) {
|
|
|
0f2bf8 |
context.Translate(Allocation.Width/2, Allocation.Height/2);
|
|
|
0f2bf8 |
hovers.Clear();
|
|
|
0f2bf8 |
if (!painting) hovers.Add(cursor);
|
|
|
0f2bf8 |
workarea.draw(context, hovers, activePoint);
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
}
|
|
|
ebcc4f |
}
|