views:

47

answers:

0

I have a winforms app that is supposed to display a tiled background and use click-and-drag to pan around. Most of the time it work but there are a few spots where it jumps in the wrong direction (for instance if I click and drag up across the center line of the form, it jumps down by about half a screen). I can't seem to find anything wrong with it.

Here is a cut down version of the code. The form is based on a default VS forms app.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        double y = 20, x = 40;
        const public float tileSize = 256;

        public Form1()
        {
            InitializeComponent();
            PositionAll();
            this.Resize += new EventHandler(Form1_Resize);
        }
        void Form1_Resize(object sender, EventArgs e) { PositionAll(); }

        Point origin;
        Point current;
        void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            current = ((Control)sender).PointToScreen(e.Location);

            if (origin != current)
            {
                var delta = Point.Subtract(current, (Size)origin);

                x -= delta.X / tileSize;
                y -= delta.Y / tileSize;
                PositionAll();
            }
        }

        void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            origin = ((Control)sender).PointToScreen(e.Location);
            current = ((Control)sender).PointToScreen(e.Location);
        }

        void PositionAll()
        {
            var size = this.ClientSize;

            int count = 0;

            var x_center = (int)Math.Floor(x);   /// this is wrong
            var y_center = (int)Math.Floor(y);
            var center = new Point(
                (int)(size.Width/2 - (x-x_center)*tileSize),
                (int)(size.Height/2 - (y-y_center)*tileSize));


            var Up = +1 + (int)Math.Ceiling(y + size.Height / 2 /tileSize);
            var Dn = -1 + (int)Math.Floor(y - size.Height / 2 /tileSize);
            var Lt = (int)Math.Floor(x - size.Width / 2 /tileSize);
            var Rt = (int)Math.Ceiling(x + size.Width / 2 /tileSize);

            for (int X = Lt; X < Rt; X++)
                for (int Y = Dn; Y < Up; Y++)
                {
                    var off = new Size(
                        (int)((X-x_center)*tileSize),    /// this is wrong
                        (int)((y_center-Y)*tileSize));
                    AddTile(X, Y, Point.Add(center,off));
                    count++;
                }
        }

        void AddTile(int X, int Y, Point p)
        {
            var it = new Label();
            it.MouseDown += new MouseEventHandler(Form1_MouseDown);
            it.MouseUp += new MouseEventHandler(Form1_MouseUp);
            it.Location = p;

            this.Controls.Add(it);
        }
    }
}


edit: found the bug (added as a comment above)