Blame mono/EllipseTruncate/MainWindow.cs

4ef489
using System;
4ef489
using System.Collections.Generic;
4ef489
4ef489
namespace EllipseTruncate {
4ef489
	public class ActivePoint {
4ef489
		public Point point;
4ef489
		public ActivePoint(double x, double y) {
4ef489
			point = new Point(x, y);
4ef489
		}
4ef489
	}
4ef489
4ef489
    public class MainWindow : Gtk.Window {
4ef489
        static public void Main() {
4ef489
        	Gtk.Application.Init();
4ef489
        	MainWindow win = new MainWindow();
4ef489
			win.Show();
4ef489
			win.Maximize();
4ef489
        	Gtk.Application.Run();
4ef489
        }
4ef489
		
782bf6
		Point cursor;
4ef489
		Point offset;
4ef489
		ActivePoint point;
782bf6
		ActiveAngleRange rangeAdd;
782bf6
		ActiveAngleRange rangeXor;
782bf6
		ActiveAngleRange rangeSub;
4ef489
		List<activepoint> points = new List<activepoint>();</activepoint></activepoint>
782bf6
		List<activeanglerange> ranges = new List<activeanglerange>();</activeanglerange></activeanglerange>
4ef489
		
4ef489
		ActivePoint ellipse0 = new ActivePoint(500.0, 500.0),
4ef489
		            ellipse1 = new ActivePoint(600.0, 500.0),
4ef489
		            ellipse2 = new ActivePoint(500.0, 450.0);
4ef489
		ActivePoint bounds0 = new ActivePoint(450.0, 500.0),
4ef489
		            bounds1 = new ActivePoint(500.0, 700.0),
4ef489
		            bounds2 = new ActivePoint(600.0, 550.0);
782bf6
		ActiveAngleRange rangeA = new ActiveAngleRange(new Point(150.0, 150.0), 50.0);
782bf6
		ActiveAngleRange rangeB = new ActiveAngleRange(new Point(400.0, 150.0), 50.0);
4ef489
		
4ef489
		public MainWindow(): base(Gtk.WindowType.Toplevel) {
4ef489
			Events = Gdk.EventMask.KeyPressMask
4ef489
				   | Gdk.EventMask.KeyReleaseMask
4ef489
			       | Gdk.EventMask.ButtonPressMask
4ef489
			       | Gdk.EventMask.ButtonReleaseMask
4ef489
			       | Gdk.EventMask.ButtonMotionMask
4ef489
			       | Gdk.EventMask.PointerMotionMask;
4ef489
			ExtensionEvents = Gdk.ExtensionMode.All;
782bf6
			rangeA.b = rangeB.a;
782bf6
			rangeB.b = rangeA.a;
4ef489
			points.AddRange(new ActivePoint[] {ellipse0, ellipse1, ellipse2, bounds0, bounds1, bounds2});
782bf6
			ranges.AddRange(new ActiveAngleRange[] {rangeA, rangeB});
4ef489
        }
4ef489
        
4ef489
        private bool refreshOnIdle()
4ef489
        	{ QueueDraw(); return false; }
4ef489
        private void Refresh() {
4ef489
        	QueueDraw(); //GLib.Idle.Add(refreshOnIdle);
4ef489
        }
4ef489
        
4ef489
        protected override bool OnDeleteEvent(Gdk.Event e) {
4ef489
			Gtk.Application.Quit();
4ef489
			return false;
4ef489
		}
4ef489
4ef489
		protected override bool OnExposeEvent(Gdk.EventExpose e) {
4ef489
            Cairo.Context context = Gdk.CairoHelper.Create(e.Window);
4ef489
4ef489
        	context.Save();
4ef489
        	context.SetSourceRGBA(1.0, 1.0, 1.0, 1.0);
4ef489
        	context.Rectangle(0, 0, Allocation.Width, Allocation.Height);
4ef489
        	context.Fill();
4ef489
        	context.Restore();
4ef489
        	context.Save();
4ef489
			context.Antialias = Cairo.Antialias.Gray;
4ef489
4ef489
			foreach(ActivePoint p in points) {
4ef489
        		context.Save();
4ef489
				context.SetSourceRGBA(0.0, point == p ? 1.0 : 0.0, 1.0, 1.0);
4ef489
				context.Arc(p.point.x, p.point.y, 5.0, 0, 2.0*Math.PI);
4ef489
				context.Fill();
4ef489
        		context.Restore();
4ef489
			}
4ef489
4ef489
			{ // draw bounds
4ef489
				Point p0 = bounds0.point, p1 = bounds1.point, p2 = bounds2.point;
4ef489
        		context.Save();
4ef489
				context.SetSourceRGBA(0.5, 0.5, 0.5, 0.2);
4ef489
				context.LineWidth = 2.0;
4ef489
				context.MoveTo(p0.x, p0.y);
4ef489
				context.LineTo(p1.x, p1.y);
4ef489
				context.LineTo(p1.x + p2.x - p0.x, p1.y + p2.y - p0.y);
4ef489
				context.LineTo(p2.x, p2.y);
4ef489
				context.ClosePath();
4ef489
				context.Stroke();
4ef489
        		context.Restore();
4ef489
			}
4ef489
        	
4ef489
			// draw ellipse
4ef489
			Ellipse ellipse = new Ellipse(ellipse0.point, ellipse1.point, ellipse2.point);
4ef489
			ellipse.drawFull(context);
4ef489
			ellipse.drawTruncated(context, bounds0.point, bounds1.point, bounds2.point);
4ef489
			
a79478
			// draw concentric grid
a79478
			ConcentricGrid cg = new ConcentricGrid(
a79478
				ellipse, 20.0, bounds0.point, bounds1.point, bounds2.point );
a79478
			cg.draw(context);
a79478
			
782bf6
			// draw ranges
782bf6
			foreach(ActiveAngleRange rl in ranges) {
782bf6
				rl.draw(context);
782bf6
				if ((cursor - rl.point).len() < 2.0*rl.radius || !rl.current.isEmpty()) {
782bf6
					context.Save();
782bf6
					context.SetSourceRGBA(0.0, 0.0, 0.0, 0.5);
782bf6
					context.LineWidth = 1.0;
782bf6
					context.MoveTo(rl.point.x, rl.point.y);
782bf6
					context.LineTo(cursor.x, cursor.y);
782bf6
					context.Stroke();
782bf6
					context.Restore();
782bf6
				}					
782bf6
			}
782bf6
			
4ef489
        	context.Restore();
4ef489
            context.Dispose();
4ef489
			return false;
4ef489
		}
782bf6
		
782bf6
		private void releaseButton() {
782bf6
			if (rangeAdd != null) rangeAdd.add();
782bf6
			if (rangeXor != null) rangeXor.xor();
782bf6
			if (rangeSub != null) rangeSub.subtract();
782bf6
			point = null;
782bf6
			rangeAdd = null;
782bf6
			rangeXor = null;
782bf6
			rangeSub = null;
782bf6
		}
4ef489
4ef489
		protected override bool OnButtonPressEvent(Gdk.EventButton e) {
782bf6
			cursor = new Point(e.X, e.Y);
782bf6
			releaseButton();
782bf6
782bf6
			ActivePoint ap = null;
782bf6
			Point o = new Point();
782bf6
		    foreach(ActivePoint p in points)
782bf6
				if ((p.point - cursor).len() <= 5.0)
782bf6
					{ o = p.point - cursor; ap = p; }
782bf6
			ActiveAngleRange ar = null;
782bf6
			uint a0 = 0;
782bf6
		    foreach(ActiveAngleRange r in ranges)
782bf6
				if ((r.point - cursor).len() < 2.0*r.radius)
782bf6
					{ ar = r; a0 = AngleRange.toUIntDiscrete((cursor - r.point).atan()); }
782bf6
4ef489
			if (e.Button == 1) {
782bf6
				if (ap != null) {
782bf6
					point = ap;
782bf6
					offset = o;
782bf6
				} else
782bf6
				if (ar != null) {
782bf6
					ar.current = new AngleRange.Entry();
782bf6
					ar.current.a0 = a0;
782bf6
					rangeAdd = ar;
782bf6
				}
782bf6
			} else
782bf6
			if (e.Button == 2) {
782bf6
				if (ar != null) {
782bf6
					ar.current = new AngleRange.Entry();
782bf6
					ar.current.a0 = a0;
782bf6
					rangeXor = ar;
782bf6
				}
782bf6
			} else
782bf6
			if (e.Button == 3) {
782bf6
				if (ar != null) {
782bf6
					ar.current = new AngleRange.Entry();
782bf6
					ar.current.a0 = a0;
782bf6
					rangeSub = ar;
782bf6
				}
4ef489
			}
782bf6
			
4ef489
			Refresh();
4ef489
			return false;
4ef489
		}
4ef489
4ef489
		protected override bool OnButtonReleaseEvent(Gdk.EventButton e) {
782bf6
			cursor = new Point(e.X, e.Y);
782bf6
			releaseButton();
4ef489
			Refresh();
4ef489
			return false;
4ef489
		}
4ef489
4ef489
		protected override bool OnMotionNotifyEvent(Gdk.EventMotion e) {
782bf6
			cursor = new Point(e.X, e.Y);
782bf6
			if (point != null) point.point = cursor + offset;
782bf6
			if (rangeAdd != null)
782bf6
				rangeAdd.current.a1 = AngleRange.toUIntDiscrete((cursor - rangeAdd.point).atan());
782bf6
			if (rangeXor != null)
782bf6
				rangeXor.current.a1 = AngleRange.toUIntDiscrete((cursor - rangeXor.point).atan());
782bf6
			if (rangeSub != null)
782bf6
				rangeSub.current.a1 = AngleRange.toUIntDiscrete((cursor - rangeSub.point).atan());
4ef489
			Refresh();
4ef489
			return false;
4ef489
		}
4ef489
    }
4ef489
}