using System;
using System.Collections.Generic;
namespace EllipseTruncate {
public class ActivePoint {
public Point point;
public ActivePoint(double x, double y) {
point = new Point(x, y);
}
}
public class MainWindow : Gtk.Window {
static public void Main() {
Gtk.Application.Init();
MainWindow win = new MainWindow();
win.Show();
win.Maximize();
Gtk.Application.Run();
}
Point offset;
ActivePoint point;
List<ActivePoint> points = new List<ActivePoint>();
ActivePoint ellipse0 = new ActivePoint(500.0, 500.0),
ellipse1 = new ActivePoint(600.0, 500.0),
ellipse2 = new ActivePoint(500.0, 450.0);
ActivePoint bounds0 = new ActivePoint(450.0, 500.0),
bounds1 = new ActivePoint(500.0, 700.0),
bounds2 = new ActivePoint(600.0, 550.0);
public MainWindow(): base(Gtk.WindowType.Toplevel) {
Events = Gdk.EventMask.KeyPressMask
| Gdk.EventMask.KeyReleaseMask
| Gdk.EventMask.ButtonPressMask
| Gdk.EventMask.ButtonReleaseMask
| Gdk.EventMask.ButtonMotionMask
| Gdk.EventMask.PointerMotionMask;
ExtensionEvents = Gdk.ExtensionMode.All;
points.AddRange(new ActivePoint[] {ellipse0, ellipse1, ellipse2, bounds0, bounds1, bounds2});
}
private bool refreshOnIdle()
{ QueueDraw(); return false; }
private void Refresh() {
QueueDraw(); //GLib.Idle.Add(refreshOnIdle);
}
protected override bool OnDeleteEvent(Gdk.Event e) {
Gtk.Application.Quit();
return false;
}
protected override bool OnExposeEvent(Gdk.EventExpose e) {
Cairo.Context context = Gdk.CairoHelper.Create(e.Window);
context.Save();
context.SetSourceRGBA(1.0, 1.0, 1.0, 1.0);
context.Rectangle(0, 0, Allocation.Width, Allocation.Height);
context.Fill();
context.Restore();
context.Save();
context.Antialias = Cairo.Antialias.Gray;
foreach(ActivePoint p in points) {
context.Save();
context.SetSourceRGBA(0.0, point == p ? 1.0 : 0.0, 1.0, 1.0);
context.Arc(p.point.x, p.point.y, 5.0, 0, 2.0*Math.PI);
context.Fill();
context.Restore();
}
{ // draw bounds
Point p0 = bounds0.point, p1 = bounds1.point, p2 = bounds2.point;
context.Save();
context.SetSourceRGBA(0.5, 0.5, 0.5, 0.2);
context.LineWidth = 2.0;
context.MoveTo(p0.x, p0.y);
context.LineTo(p1.x, p1.y);
context.LineTo(p1.x + p2.x - p0.x, p1.y + p2.y - p0.y);
context.LineTo(p2.x, p2.y);
context.ClosePath();
context.Stroke();
context.Restore();
}
// draw ellipse
Ellipse ellipse = new Ellipse(ellipse0.point, ellipse1.point, ellipse2.point);
ellipse.drawFull(context);
ellipse.drawTruncated(context, bounds0.point, bounds1.point, bounds2.point);
context.Restore();
context.Dispose();
return false;
}
protected override bool OnButtonPressEvent(Gdk.EventButton e) {
if (e.Button == 1) {
Point cursor = new Point(e.X, e.Y);
point = null;
foreach(ActivePoint p in points)
if ((p.point - cursor).len() <= 5.0)
{ offset = p.point - cursor; point = p; }
}
Refresh();
return false;
}
protected override bool OnButtonReleaseEvent(Gdk.EventButton e) {
if (e.Button == 1) point = null;
Refresh();
return false;
}
protected override bool OnMotionNotifyEvent(Gdk.EventMotion e) {
if (point != null) {
Point cursor = new Point(e.X, e.Y);
point.point = cursor + offset;
}
Refresh();
return false;
}
}
}