Solved

Help me with drag and drop

Posted on 2013-11-22
25
297 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 13
  • 12
25 Comments
 
LVL 31

Expert Comment

by:Marco Gasi
ID: 39672332
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 31

Expert Comment

by:Marco Gasi
ID: 39672518
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 31

Expert Comment

by:Marco Gasi
ID: 39672524
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:hidrau
ID: 39672579
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
ID: 39672604
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 31

Expert Comment

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

Author Comment

by:hidrau
ID: 39672633
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 31

Expert Comment

by:Marco Gasi
ID: 39672660
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 31

Expert Comment

by:Marco Gasi
ID: 39672670
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
ID: 39672696
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 31

Expert Comment

by:Marco Gasi
ID: 39672706
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
ID: 39672715
:) We are reach over there lol;

MarqusG, just curiosity, where are you from?

I am from Brazil - São Paulo
0
 
LVL 31

Expert Comment

by:Marco Gasi
ID: 39672725
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
ID: 39672727
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 31

Expert Comment

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

Author Comment

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

Expert Comment

by:Marco Gasi
ID: 39672811
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 31

Expert Comment

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

Author Comment

by:hidrau
ID: 39672843
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 31

Accepted Solution

by:
Marco Gasi earned 500 total points
ID: 39672892
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
ID: 39673029
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 31

Expert Comment

by:Marco Gasi
ID: 39673044
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
ID: 39673053
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
ID: 39673055
thanks very very much!!!
0
 
LVL 1

Author Comment

by:hidrau
ID: 39673111
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Reconfigure Delphi Install? 2 78
Adoquery sql  left join does not work 25 121
Firemonkey BASS_Init into a thread 17 85
delphi popmenu non latine charcters 3 49
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Finding and deleting duplicate (picture) files can be a time consuming task. My wife and I, our three kids and their families all share one dilemma: Managing our pictures. Between desktops, laptops, phones, tablets, and cameras; over the last decade…

752 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