Solved

Help me with drag and drop

Posted on 2013-11-22
25
289 Views
Last Modified: 2013-11-24
Hello Guys

I need a help.

I am trying to do a small game with pictures, but I am having trouble with drag and drop function.

I put an small example in image what I want to do.  As you can see, I have three panels.
The first one is the panel where is all my images, and the panel 2, is the place where I need
to drop the images. The 3 panel is only the example as my second panel must be after dropping the image.

My doubts are:

1) Drag the image from Panel 1 to the  panel2.

2) The panel 2 will only accept three images, for example: pict5, pict1 and pict3.

3) When I drop the picture in the panel2, the figure must be align in the center of the panel, vertical and horizontal center.

4) when dropped more than 1 picture, they must be spaced and centered as you can see the panel3 as example.


My example was made in Delphi XE4

Thanks
Alexandre
IMG1.jpg
Unit1.dfm
Unit1.pas
Project1.dpr
0
Comment
Question by:hidrau
  • 13
  • 12
25 Comments
 
LVL 30

Expert Comment

by:Marco Gasi
Comment Utility
This is the code I use to implement drag and drop in your project (let me some time to play with alignement):

Unit1.pasUnit1.dfmProject1.dpr
0
 
LVL 30

Expert Comment

by:Marco Gasi
Comment Utility
Mmmmhh, ordering images is difficult: how has the behavior to be? Do you want the user can choose the place of each image whan he drops it on the panel? Or you want the position is random?
0
 
LVL 30

Expert Comment

by:Marco Gasi
Comment Utility
Okay, see if this is a good solution for you: it has not that automatically reallignement I wa looking for, but it works.

DragDropImages.zip
0
 
LVL 1

Author Comment

by:hidrau
Comment Utility
Hello MarquG,

Thanks very very much for helping me.

I'm gonna try it now and let you know about it.
0
 
LVL 1

Author Comment

by:hidrau
Comment Utility
MarqusG, you are right, the problem is being now the reallignement.

I changed the panel to receive 5 figures, and according to dropping the figures on it, the figures must reallign on the panel.

Change the recival value to 5 and drop 5 figures on it, you wil see them,

I am trying to do it, but I don't have many idea how to do it. Take a look at it and tell me if you can help me to realign the figures.
0
 
LVL 30

Expert Comment

by:Marco Gasi
Comment Utility
Please, tell me about the principle of the realignement: does the first slide to the left?
0
 
LVL 1

Author Comment

by:hidrau
Comment Utility
Hello MarqusG,

I am trying but I haven't got it yet :)

when I drop the first figure, it must align to the center and so on with another.

Well, I inserted a code of mine and I am almost reach the result.

Take a look at:

procedure TForm1.Panel1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
 a, b, c : Integer;

begin
  if (Source is TImage) and (Panel1.ControlCount < 5) then
  begin
    TImage(Source).Parent := Panel1;
    TImage(Source).Left := 115 + ((TImage(Source).Width + 15) * (Panel1.ControlCount - 1));
  end;

  a := (sender as TPanel).ControlCount;
  a := a * 60;
  b := ((sender as Tpanel).Width - a) div ((sender as TPanel).ControlCount+1);

  For c := 0 to (sender as TPanel).ControlCount-1 do
  Begin
    if ((sender as TPanel).Controls[c] is TImage)  then
    Begin
      ((sender as TPanel).Controls[c] as TImage).Left := b;
      b := b + 60 + 15;
    End;
  End;


end;

Open in new window


Maybe you can have another idea on it or another way to do it. Let me know
0
 
LVL 30

Expert Comment

by:Marco Gasi
Comment Utility
Wow, well done, I'll try to play me too. But I changed (sender as TPanel) to Panel1, which is the one where the images have to be aligned.
0
 
LVL 30

Expert Comment

by:Marco Gasi
Comment Utility
I think I got it. Add this procedure:

procedure TForm1.AlignImages(Container: TObject);
var
  a, b, c, Factor: Integer;
begin
  case Panel1.ControlCount of
  1: Factor := Panel1.ControlCount+1;
  2: Factor := Panel1.ControlCount;
  3: Factor := Panel1.ControlCount -1;
  4: Factor := Panel1.ControlCount -1;
  5: Factor := Panel1.ControlCount -1;
  end;
  a := Panel1.ControlCount;
  a := a * 60;
  b := (Panel1.Width - a) div Factor;

  For c := 0 to Panel1.ControlCount-1 do
  Begin
    if (Panel1.Controls[c] is TImage)  then
    Begin
      (Panel1.Controls[c] as TImage).Left := b;
      b := b + 60 + 15;
    End;
  End;
end;

Open in new window


and call it here:

procedure TForm1.Panel1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
  if (Source is TImage) and (Panel1.ControlCount < 5) then
    TImage(Source).Parent := Panel1;
  AlignImages(Panel1);
end;

Open in new window

0
 
LVL 1

Author Comment

by:hidrau
Comment Utility
MarqusG,

Yeah, I also made a small change.

I changed the function in a more generic function, where it can work with any container.

Take a look at it:

procedure AlinhaImages(Container: TObject; spaceBetween: Integer);
var
  a, b, c, Factor, OBJwidth: Integer;
begin
  case (Container as TPanel).ControlCount of
    1: Factor := (Container as TPanel).ControlCount+1;
    2: Factor := (Container as TPanel).ControlCount;
    3: Factor := (Container as TPanel).ControlCount -1;
    4: Factor := (Container as TPanel).ControlCount -1;
    5: Factor := (Container as TPanel).ControlCount -1;
  end;

  OBJwidth := ((Container as TPanel).Controls[0] as TImage).Width;

  a := (Container as TPanel).ControlCount;
  a := a * OBJwidth;
  b := ((Container as TPanel).Width - a) div Factor;

  For c := 0 to (Container as TPanel).ControlCount-1 do
  Begin
    if ((Container as TPanel).Controls[c] is TImage)  then
    Begin
      ((Container as TPanel).Controls[c] as TImage).Left := b;
      b := b + OBJwidth + spaceBetween;
    End;
  End;
end;

Open in new window



Well, it is almost there, the align it is not perfect yet and you can notice that the left side is smaller than right side. What do you think it is missing to the align be perfect?
0
 
LVL 30

Expert Comment

by:Marco Gasi
Comment Utility
Lol, I also had made some change: i pass the spaceBetween and in addition the width of the control itself...

Anyway, I'll go to play ;)
0
 
LVL 1

Author Comment

by:hidrau
Comment Utility
:) We are reach over there lol;

MarqusG, just curiosity, where are you from?

I am from Brazil - São Paulo
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 30

Expert Comment

by:Marco Gasi
Comment Utility
I'm from Italy, a small, small town near Monza (do you like Formula 1?) But i'm going to move me and my family to Tenerife, Canary Islands.
0
 
LVL 1

Author Comment

by:hidrau
Comment Utility
I just asked because we change idea with many people and we don't have any idea where the people are from. I have heard about Monza, one day I hope to know Italy and other parts of the world.

Thanks marqusG for helping me with this. :)

do you have skype? if so and if you want, mine is alexhaifa
0
 
LVL 30

Expert Comment

by:Marco Gasi
Comment Utility
Sorry, no skype yet - and my english is better if written than if spoken :)
0
 
LVL 1

Author Comment

by:hidrau
Comment Utility
MarqusG, did you get a better/perfect align? I am trying but nothing yet here.
0
 
LVL 30

Expert Comment

by:Marco Gasi
Comment Utility
I'm trying too but no good news. There is a progressive sliding to the left and I can't get rid off of it.

These are the values that Image.Left should have accordingly to the number of images:

1:  195
2:  155 - 235
3:  118 - 198 - 273
4:  78 - 158 - 238 - 313
5:  40 - 120 - 200 - 275 - 350

And these are the real value I get with code:

a Panel1.ControlCount = 1
a Panel1.ControlCount * Width = 60
b Panel1.Width - a) div Factor = 450 - 60 div 2 = 195
Left of Image 0 = 195
a Panel1.ControlCount = 2
a Panel1.ControlCount * Width = 120
b Panel1.Width - a) div Factor = 450 - 120 div 2 = 165
Left of Image 0 = 165
Left of Image 1 = 240
a Panel1.ControlCount = 3
a Panel1.ControlCount * Width = 180
b Panel1.Width - a) div Factor = 450 - 180 div 2 = 135
Left of Image 0 = 135
Left of Image 1 = 210
Left of Image 2 = 285
a Panel1.ControlCount = 4
a Panel1.ControlCount * Width = 240
b Panel1.Width - a) div Factor = 450 - 240 div 3 = 70
Left of Image 0 = 70
Left of Image 1 = 145
Left of Image 2 = 220
Left of Image 3 = 295
a Panel1.ControlCount = 5
a Panel1.ControlCount * Width = 300
b Panel1.Width - a) div Factor = 450 - 300 div 4 = 37
Left of Image 0 = 37
Left of Image 1 = 112
Left of Image 2 = 187
Left of Image 3 = 262
Left of Image 4 = 337

Do you wish get crazy you too? ;)
0
 
LVL 30

Expert Comment

by:Marco Gasi
Comment Utility
I have to stop a bit. I'll cmoe back later. Bye
0
 
LVL 1

Author Comment

by:hidrau
Comment Utility
Yeah, it is really hard.

Of course, it must have a way to do that. I will also stop a little bit and return later.
0
 
LVL 30

Accepted Solution

by:
Marco Gasi earned 500 total points
Comment Utility
Yeah, I got it just now! I totally rewrote the procedure AlignImages: it was a bad approach that mess code:
  case (Container as TPanel).ControlCount of
    1: Factor := (Container as TPanel).ControlCount+1;
    2: Factor := (Container as TPanel).ControlCount;
    3: Factor := (Container as TPanel).ControlCount -1;
    4: Factor := (Container as TPanel).ControlCount -1;
    5: Factor := (Container as TPanel).ControlCount -1;
  end;
  ...

Open in new window


There was no sense in that. This you find the new one.

procedure TForm1.AlignImages(Container: TObject; W, M: Integer);
var
  I, ImgCount, TotalWidth, TotalMargin, TotalSpaceRequired, ImgLeft: Integer;
  Img: TImage;
begin
  ImgCount := Panel1.ControlCount;
  TotalWidth := W* ImgCount;
  TotalMargin := M * (ImgCount-1);
  TotalSpaceRequired := TotalWidth + TotalMargin;
  ImgLeft := (Panel1.Width div 2) - (TotalSpaceRequired div 2);
  for I := 0 to Panel1.ControlCount - 1 do
  begin
    if (Panel1.Controls[I] is TImage) then
    begin
      Img := TImage(Panel1.Controls[I]);
      Img.Left := ImgLeft;
      ImgLeft := ImgLeft + W + M;
    end;
  end;
end;

Open in new window


I give you the whole project with some debug tips (2 labels and a memo to follow the process) and you'll can see that values are almost precises: 1 unit variations due to the division.
Note: I've increased the width of the Panel1: from 449 to 450. A stupid thing, but why get float numbers rounded (449 div 2 = 224,5), when you can get directly integers?

Hope this makes you happy as it makes me.
Cheers
DragDropImages.zip
0
 
LVL 1

Author Comment

by:hidrau
Comment Utility
wow, you are right, I can't believe.

Thanks very very much for your help. It helped me a lot and it got perfect.

You are very good at Delphi. I am not as good as you, I am just started with some kinds different from my kind of proclamation.
0
 
LVL 30

Expert Comment

by:Marco Gasi
Comment Utility
What you mean saying "I am just started with some kinds different from my kind of proclamation"?

This apart, thank you for nice words, but you'll find a lot of guys mutch mucth better than me here at EE :)

Cheers
0
 
LVL 1

Author Comment

by:hidrau
Comment Utility
Those words mean:

I work with Delphi only for company system with database, reports, grids, form for to insert (name, address, phone, etc)

This kind of project is the first that I will have to use some function and knowledge very different that I used to do everyday. :)

Now, that everything is ok, I have a second and third part that I will start. I am gonna open another thread for the second part.
0
 
LVL 1

Author Closing Comment

by:hidrau
Comment Utility
thanks very very much!!!
0
 
LVL 1

Author Comment

by:hidrau
Comment Utility
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now