Jul 1, 2009

Windows Mobile 6 with C# (compass control)

Actually the textual representation did not look to great. So I decided to look for a free .NET mobile compass control - which I did not find.

Let's hack some dirty user control drawing code:

/// <summary>

/// Paints the control.

/// </summary>

/// <param name="e"></param>

protected override void OnPaintBackground(PaintEventArgs e)

{

    base.OnPaintBackground(e);

 

    int penWidth = 5;

    using (Graphics g = this.CreateGraphics())

    using (Pen penBlackThin = new Pen(Color.Black, penWidth - 3))

    using (Pen penBlack = new Pen(Color.Black, penWidth))

    using (Pen penDarkGray = new Pen(Color.DarkGray, penWidth))

    using (Pen penRed = new Pen(Color.Red, penWidth + 3))

    using (Pen penWhite = new Pen(Color.WhiteSmoke, penWidth + 3))

    using (Brush brushDarkGray = new SolidBrush(Color.DarkGray))

    using (Brush brushWhite = new SolidBrush(Color.White))

    using (Brush brushLightGray = new SolidBrush(Color.LightGray))

    using (Brush brushRed = new SolidBrush(Color.Red))

    {

        double radius = (this.ClientRectangle.Width - 50) / 2;

        double radiusInner = (this.ClientRectangle.Width - 70) / 2;

        int xcenter = this.ClientRectangle.Width / 2;

        int ycenter = this.ClientRectangle.Height / 2;

        float halfFont = this.Font.Size / 2;

 

        // g.Clear(this.BackColor);

 

        // draw circles

        g.FillEllipse(brushLightGray, penWidth, penWidth, this.ClientRectangle.Width - 2 * penWidth, this.ClientRectangle.Height - 2 * penWidth);

        g.DrawEllipse(penDarkGray, penWidth, penWidth, this.ClientRectangle.Width - 2 * penWidth, this.ClientRectangle.Height - 2 * penWidth);

        g.DrawEllipse(penBlack, 2 * penWidth, 2 * penWidth, this.ClientRectangle.Width - 4 * penWidth, this.ClientRectangle.Height - 4 * penWidth);

 

        // draw separator lines

        for (int l = 0; l < 16; l++)

        {

            double angle = l * 22.5 + this.Heading;

            double xout = Math.Sin(this.ToRadian(angle)) * radiusInner;

            double yout = Math.Cos(this.ToRadian(angle)) * radiusInner;

            double xin = Math.Sin(this.ToRadian(angle)) * (radiusInner - 2 * this.Font.Size);

            double yin = Math.Cos(this.ToRadian(angle)) * (radiusInner - 2 * this.Font.Size);

            g.DrawLine(penBlackThin, (int)xout + xcenter, (int)yout + ycenter, (int)xin + xcenter, (int)yin + ycenter);

        }

 

        // draw N, W, E, S

        double x = Math.Sin(this.ToRadian(this.Heading)) * radius;

        double y = Math.Cos(this.ToRadian(this.Heading)) * radius;

        g.DrawString("N", this.Font, brushRed, (float)(xcenter - x) - halfFont, (float)(ycenter - y) - halfFont);

        g.DrawString("S", this.Font, brushRed, (float)(xcenter + x) - halfFont, (float)(ycenter + y) - halfFont);

        g.DrawString("W", this.Font, brushRed, (float)(xcenter - y) - halfFont, (float)(ycenter + x) - halfFont);

        g.DrawString("E", this.Font, brushRed, (float)(xcenter + y) - halfFont, (float)(ycenter - x) - halfFont);

 

        // draw needle

        g.DrawLine(penWhite, xcenter, ycenter, xcenter, this.ClientRectangle.Height - 50);

        g.DrawLine(penRed, xcenter, 50, xcenter, ycenter);

 

        // draw digital heading

        g.FillRectangle(brushWhite, (int)(xcenter - 11 * halfFont), (int)(ycenter - 5 * halfFont), (int)(22 * halfFont), (int)(11 * halfFont));

        g.DrawString(string.Format("{0,3:000}°", this.Heading), this.Font, brushRed, xcenter - 4 * halfFont, ycenter - 5 * halfFont);

 

        // draw height above sea level

        g.DrawString(string.Format("{0,4:0000.0}m", this.Height), this.Font, brushRed, xcenter - 10 * halfFont, ycenter);

    }

}



which looks about this on the device:


Needs some adjustments, especially to look great on other screen resolutions too. Maybe later ...

2 comments: