/// <summary> /// Renders the key in the specified surface. /// </summary> /// <param name="g">The GDI+ surface to render on.</param> /// <param name="speed">The speed of the mouse.</param> public void Render(Graphics g, SizeF speed) { var subStyle = GlobalSettings.CurrentStyle.TryGetElementStyle <MouseSpeedIndicatorStyle>(this.Id) ?? GlobalSettings.CurrentStyle.DefaultMouseSpeedIndicatorStyle; // Small circles have a fifth of the radius of the full control. var smallRadius = (float)this.Radius / 5; // The sensitivity is a factor over the mouse speed. var sensitivity = GlobalSettings.Settings.MouseSensitivity / (float)100; // The total length is determined by the sensitivity, speed and radius. But never more than the radius. var pointerLength = (int)Math.Min(this.Radius, sensitivity * speed.GetLength() * this.Radius); var colorMultiplier = Math.Max(0, Math.Min(1, (float)pointerLength / this.Radius)); Color color1 = subStyle.InnerColor; Color outerColor = subStyle.OuterColor; // The second color should be averaged over the two specified colours, based upon how far out the thingymabob is. var color2 = Color.FromArgb( (int)(color1.R * (1 - colorMultiplier) + outerColor.R * colorMultiplier), (int)(color1.G * (1 - colorMultiplier) + outerColor.G * colorMultiplier), (int)(color1.B * (1 - colorMultiplier) + outerColor.B * colorMultiplier)); // Draw the edge. g.DrawEllipse( new Pen(color1, subStyle.OutlineWidth), Geom.CircleToRectangle(this.Location, this.Radius)); // Only calculate the pointer data if it has some length. if (pointerLength > 0) { // Determine the angle of the pointer. var angle = speed.GetAngle(); // Determine the location of the pointer end. var pointerEnd = this.Location.CircularTranslate(pointerLength, angle); // If the pointer doesn't end where it starts, draw it. if (pointerEnd.X != this.Location.X || pointerEnd.Y != this.Location.Y) { // Draw the pointer, as a pie. g.FillPie( new LinearGradientBrush(this.Location, pointerEnd, color1, color2), Geom.CircleToRectangle(this.Location, pointerLength), Geom.RadToDeg(angle) - 10, 20); // Draw a circle on the outter edge in the direction of the pointer. var pointerEdge = this.Location.CircularTranslate(this.Radius, angle); g.FillEllipse(new SolidBrush(color2), Geom.CircleToRectangle(pointerEdge, (int)smallRadius)); } } // Draw the circle in the center. g.FillEllipse(new SolidBrush(color1), Geom.CircleToRectangle(this.Location, (int)smallRadius)); }