Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Move shapes with arrow keys (Read 3583 times)
Dexter
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 62
Joined: Jun 25th, 2009
Move shapes with arrow keys
Aug 20th, 2010 at 7:45am
Print Post  
Hi there,

I have come with some code that moves shapes using arrow keys. But the result is not the same as moving the shape with the mouse, meaning the diagram does not scroll if the shape goes out of the visible part of the diagram. I have auto scroll set to true.

In general on the PreviewKeyDown event of the diagram view is the key is an arrow then I set the IsInputKey value to true. This will fire the key down, and key up event. In the PreviewKeyDown event I start an interaction on the shape I want to move. On the keyDown I call the update and isAllowed method on the interaction and on key up the complete method on the interaction. This work fine but he diagram does not scroll for the shape like when I move the shape with the mouse.

If in the Key events I send some messages, like mouse down, mouse move and mouse up, to scroll the diagram, I get an error "Value can not be null. Parameter name image".

Can any body give me an idea about this problem.

Regards,
Dexter
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Move shapes with arrow keys
Reply #1 - Aug 20th, 2010 at 9:15am
Print Post  
Hi,

Call view.ClientToDoc(view.ClientRectangle) to get the visible region of the diagram. Check if it contains the items' bounding rectangle, and if it doesn't, change either ScrollX or ScrollY depending on the arrow key:

left arrow: ScrollX -= viewRect.Left - itemsRect.Left;
right arrow: ScrollX += itemsRect.Right - viewRect.Right;
up arrow: ScrollY -= viewRect.Top - itemsRect.Top;
down arrow: ScrollY += itemsRect.Bottom - viewRect.Bottom;

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Dexter
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 62
Joined: Jun 25th, 2009
Re: Move shapes with arrow keys
Reply #2 - Aug 20th, 2010 at 9:26am
Print Post  
Hi Stoyan,

You are correct abut this. It could be a solution.
Now during some testing to see if the code will work I see that the error about the image appears also if I move the shape with the keys (like I described) and I press the mouse left button. (to be clear: I DO NOT SEND THE MESSAGE mouse down)

Do you have any idea why?

Regards,
Dexter
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Move shapes with arrow keys
Reply #3 - Aug 23rd, 2010 at 8:23am
Print Post  
Could you copy your KeyDown handler code here?
  
Back to top
 
IP Logged
 
Dexter
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 62
Joined: Jun 25th, 2009
Re: Move shapes with arrow keys
Reply #4 - Aug 23rd, 2010 at 8:38am
Print Post  
Hi Stoyan,

Here is the code for all the things I do:

[code]

    public partial class Form1 : Form
    {
       private Timer t;

       private bool arrowKeyDown;
       private List<Keys> keyDown;
       private List<Keys> keyUp;

       public Form1()
       {
           InitializeComponent();
       }

       private void Form1_Load(object sender, EventArgs e)
       {
           ShapeNode shape = new ShapeNode(this.diagram1);
           this.diagram1.Nodes.Add(shape);
           shape.Image = null;

           shape.Move(50, 50);

           this.diagram1.Selection.Change(shape);

           t = new Timer();
           t.Interval = 300;
           t.Tick += new EventHandler(time_Tick);
       }

       private void time_Tick(object sender, EventArgs e)
       {
           t.Stop();

           List<int> downKeysASCII = this.keyDown.Select(p => (int)p).Distinct().OrderBy(p => p).ToList();
           List<int> upKeysASCII = this.keyUp.Select(p => (int)p).Distinct().OrderBy(p => p).ToList();

           if (downKeysASCII.SequenceEqual(upKeysASCII) && this.diagram1.Interaction != null)
           {
               arrowKeyDown = false;
               Console.WriteLine("Save");

               DiagramNode firstNode = this.diagram1.Selection.Nodes[0];
               this.diagram1.Interaction.Complete(firstNode.GetCenter(), this.diagram1);

               this.diagram1.Interaction = null;

               this.diagram1.Invalidate();
           }
       }

       private void diagramView1_KeyDown(object sender, KeyEventArgs e)
       {
           this.keyDown.Add(e.KeyData);

           if (arrowKeyDown)
           {
               DiagramNode firstNode = this.diagram1.Selection.Nodes[0];
               PointF firstNodeCenter = firstNode.GetCenter();

               if (e.KeyCode == Keys.Right)
               {
                   firstNodeCenter.X += 4;
               }
               if (e.KeyCode == Keys.Left)
               {
                   firstNodeCenter.X -= 4;
               }
               if (e.KeyCode == Keys.Down)
               {
                   firstNodeCenter.Y += 4;
               }
               if (e.KeyCode == Keys.Up)
               {
                   firstNodeCenter.Y -= 4;
               }

               Cursor.Position = diagramView1.PointToScreen(this.diagramView1.DocToClient(firstNodeCenter));

               //uint lParam = MakeLong(Cursor.Position.X, Cursor.Position.Y);
               //SendMessage(this.diagramView1.Handle, (int)Msgs.WM_MOUSEMOVE, 0, lParam);

               // Cursor.Position = newCursorPosition;

               if (e.KeyData == Keys.Escape)
               {
                   this.diagram1.Interaction.Cancel(this.diagram1);
                   this.diagram1.Interaction = null;
                   arrowKeyDown = false;
               }
               else
               {
                   this.diagram1.Interaction.Update(firstNodeCenter, this.diagram1);
                   bool allowModify = this.diagram1.Interaction.IsAllowed(firstNodeCenter);
               }

               this.diagram1.Invalidate();
           }
       }

       private void diagramView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
       {
           if (this.diagram1.Selection.Nodes.Count > 0 &&
               (e.KeyCode == Keys.Right || e.KeyCode == Keys.Left || e.KeyCode == Keys.Up || e.KeyCode == Keys.Down))
           {
               if (!arrowKeyDown)
               {
                   DiagramNode firstNode = this.diagram1.Selection.Nodes[0];

                   Point newCursorPosition = this.diagramView1.PointToScreen(this.diagramView1.DocToClient(firstNode.GetCenter()));

                   Console.WriteLine("start interaction");

                   uint lParam = MakeLong(Cursor.Position.X, Cursor.Position.Y);
                   //SendMessage(this.diagramView1.Handle, (int)Msgs.WM_LBUTTONDOWN, 0, lParam);

                   Cursor.Position = newCursorPosition;

                   this.diagram1.Interaction = new InteractionState(firstNode, 8, MindFusion.Diagramming.Action.Modify);
                   this.diagram1.Interaction.Start(firstNode.GetCenter(), diagram1);

                   this.keyUp = new List<Keys>();
                   this.keyDown = new List<Keys>();
               }

               arrowKeyDown = true;

               e.IsInputKey = true;
               t.Stop();
           }
       }

       private uint MakeLong(int low, int high)
       {
           return (uint)((high << 16) + low);
       }

       private void diagramView1_KeyUp(object sender, KeyEventArgs e)
       {
           this.keyUp.Add(e.KeyData);

           if (this.diagram1.Selection.Nodes.Count > 0 &&
               (e.KeyCode == Keys.Right || e.KeyCode == Keys.Left || e.KeyCode == Keys.Up || e.KeyCode == Keys.Down))
           {
               t.Start();
           }
       }
    }

[/code]

This is all the code there is in the application.

Regards,
Dexter
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Move shapes with arrow keys
Reply #5 - Aug 24th, 2010 at 8:00am
Print Post  
Hi Dexter,

Set Behavior = DoNothing when calling interaction.Start and reset it to its original value after Complete / Cancel to make this work. For the next release we'll try to integrate keyboard handling into the Behavior class to have an official way of implementing such scenarios.

Stoyan
  
Back to top
 
IP Logged
 
Dexter
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 62
Joined: Jun 25th, 2009
Re: Move shapes with arrow keys
Reply #6 - Aug 24th, 2010 at 9:06am
Print Post  
Hi Stoyan,

I see now that you have started to test the 5.4 beta version. Is the keyboard handling programmed to be included in 5.4 or it will be included in a future version. This has an impact whether or not to continue to implement the behavior my self.

Best regards,
Dexter
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Move shapes with arrow keys
Reply #7 - Aug 24th, 2010 at 9:47am
Print Post  
Hi Dexter,

It won't make it for this release, but for 5.4.1 in a couple of months.

Stoyan
  
Back to top
 
IP Logged
 
Dexter
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 62
Joined: Jun 25th, 2009
Re: Move shapes with arrow keys
Reply #8 - Aug 24th, 2010 at 10:06am
Print Post  
OK! Thank you
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint