Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Reactive Mouse Headings (see http://rebcabin.wordpress.com)
<Query Kind="Program">
<Namespace>System.Windows.Forms</Namespace>
<Namespace>System.Reactive.Linq</Namespace>
<Namespace>System.Reactive</Namespace>
<Namespace>System.Drawing</Namespace>
</Query>
void Main()
{
// Don't forget to F4 and include all the Reactive Framework DLLs from
// http://rx.codeplex.com. I have them in my LINQPad Plugins folder,
// and that's why they don't show up in the list above -- they're
// automatically included in every one of my LINQPad scripts.
var form = new Form();
var g = form.CreateGraphics();
var pens = new []
{ new Pen(Color.FromKnownColor(KnownColor.Red), 10),
new Pen(Color.FromKnownColor(KnownColor.Green), 10),
new Pen(Color.FromKnownColor(KnownColor.Blue), 10),
new Pen(Color.FromKnownColor(KnownColor.Orange), 10)
};
var font = new Font(FontFamily.GenericMonospace, 36, FontStyle.Bold);
var brush = new SolidBrush(Color.FromKnownColor(KnownColor.BlueViolet));
var backgroundBrush = new SolidBrush(SystemColors.Window);
var textPoint = new Point(0, 0);
var mms = Observable
.FromEventPattern<MouseEventArgs>(form, "MouseMove")
;
Func<double, double, double> RadiansFromDyDx =
(dy, dx) => ((Math.Atan2(dy, dx) + 2 * Math.PI) % (2 * Math.PI));
Func<double, double, int> DegreesFromDyDx =
(dy, dx) => ((int)(RadiansFromDyDx(dy, dx) * 180 / Math.PI));
Func<double, double, int> RotatedQuadrantFromDyDx =
(dy, dx) => ((int)((Math.Atan2(dy, dx) + 9 * Math.PI / 4) * 2 / Math.PI)) % 4;
var headings = mms.Zip(mms.Skip(1), (@from, @to) => {
var dx = @to.EventArgs.X - @from.EventArgs.X;
var dy = @to.EventArgs.Y - @from.EventArgs.Y;
return new
{ @from = new Point(@from.EventArgs.X, @from.EventArgs.Y),
@to = new Point(@to.EventArgs.X, @to.EventArgs.Y),
angle = DegreesFromDyDx(-dy, dx),
heading = RotatedQuadrantFromDyDx(-dy, dx)
}; });
Thread.CurrentThread.ManagedThreadId.Dump("Subscribing on Thread ID");
headings
.Select(h => new { h.angle, h.heading })
.DistinctUntilChanged(h => h.angle)
.Subscribe(h =>
{ Console.WriteLine("[{2}]: {0}, {1}", h.heading, h.angle,
Thread.CurrentThread.ManagedThreadId);
})
;
headings
.Subscribe(h => g.DrawLine(pens[h.heading], h.@from, h.@to))
;
var headingNames = new [] {"E", "N", "W", "S"};
headings
.Select(d => d.heading)
.DistinctUntilChanged()
.Subscribe(h =>
{ g.FillRectangle(backgroundBrush, textPoint.X, textPoint.Y, 48, 48);
g.DrawString(headingNames[h], font, brush, textPoint);
});
;
// Application.Run blocks -- no code after this line will run.
Application.Run(form);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment