Recent

Author Topic: [SOLVED] Strange behavior after a drag and drop  (Read 8742 times)

valter.home

  • Jr. Member
  • **
  • Posts: 81
[SOLVED] Strange behavior after a drag and drop
« on: May 17, 2021, 10:22:25 am »
Sorry for the unclear title of the post but i didn't know how to describe the problem in one line.
At runtime in a TScrollBox I create panels which can contain different components.
The panels are created in succession one above the other.
For clarity let's imagine we have Panel1 as the first panel, Panel2 below and then Panel3.
If I iterate the TScrollBox simply
Code: Pascal  [Select][+][-]
  1. for i:=0 to ScrollBox1.ComponentCount-1 do
  2. begin
  3.   GetContainer:=ScrollBox1.Components[i] as TPanel;
  4.   Memo1.Lines.Add(GetContainer.Name);
  5. end;
I get the names of the panels in sequence correctly.
Then I perform a Drag by moving the panels to different positions, for example Panel2, Panel3, Panel1.
Using the same code I keep getting Panel1, Panel2, Panel3.
Does this mean that the panels are stored according to the sequence of creation?
Is there a way to read their actual position from first to last?

« Last Edit: May 21, 2021, 06:01:07 pm by valter.home »

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Strange behavior after a drag and drop
« Reply #1 on: May 17, 2021, 10:54:11 am »
Does this mean that the panels are stored according to the sequence of creation?

Yes.

Quote
Is there a way to read their actual position from first to last?

AFAICT, Not in such an easy way; you'll have to read their coordinates and sort them accordingly.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

valter.home

  • Jr. Member
  • **
  • Posts: 81
Re: Strange behavior after a drag and drop
« Reply #2 on: May 17, 2021, 11:03:33 am »
Thanks lucamar.
Too bad but it can be solved as you say by keeping track of the movements.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Strange behavior after a drag and drop
« Reply #3 on: May 17, 2021, 08:23:21 pm »
The attached simple example shows one way to do drag and drop with dynamically created controls.

valter.home

  • Jr. Member
  • **
  • Posts: 81
Re: Strange behavior after a drag and drop
« Reply #4 on: May 18, 2021, 11:45:22 pm »
Thanks for your reply but maybe due to my bad english i got misunderstood.
My difficulty is not to create controls at runtime nor to move them by drag and drop but to read the final position of the controls in sequence starting from the first.
I looked at your code, if I move panel 4 to position 1, panel 1 takes the position of 4. In my case, panel 1 must go down under panel 4.
But this is not the problem because I already do it.
The real problem is that I create for example 5 panels (one on top of the other as in your demo), then I move panel 5 in place of 2 which moves to the third position.
I need to read the position of the panels after any movements, in the mentioned case I should have: 1,5,2,3,4
But if I iterate after moving using:

Code: Pascal  [Select][+][-]
  1. for i:= 0 to scrollbox1.ComponentCount-1 do

I always get 1,2,3,4,5 whatever the position of the panels after each move.
In fact, if in your example I add a TButton and a TMemo

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   i: integer;
  4. begin
  5.   for i:= 0 to scrollbox1.ComponentCount-1 do
  6.   begin
  7.     memo1.lines.add(scrollbox1.Components[i].Tag.ToString);
  8.   end;
  9. end;

then I move panel 5 to position 2 on the screen I see 0,4,2,3,1 but in TMemo I will have 0,1,2,3,4.



engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Strange behavior after a drag and drop
« Reply #5 on: May 19, 2021, 03:01:15 am »
It sounds to me you want the z-order. Use Controls instead of Components

Quote
The index also indicates the Z-order of the child controls, zero for the topmost.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   i: integer;
  4. begin
  5.   for i:= 0 to scrollbox1.ControlCount-1 do
  6.     memo1.append(scrollbox1.Controls[i].Tag.ToString);
  7. end;
« Last Edit: May 19, 2021, 03:14:13 am by engkin »

valter.home

  • Jr. Member
  • **
  • Posts: 81
Re: Strange behavior after a drag and drop
« Reply #6 on: May 19, 2021, 08:59:11 am »
Unfortunately I have already considered the z-order but nothing changes. Both using Component and Control the reading of the objects in the TScrollBox takes place according to the creation sequence, ignoring their current position.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Strange behavior after a drag and drop
« Reply #7 on: May 19, 2021, 10:58:01 am »
Try to make a small project to show us how you move the panels

valter.home

  • Jr. Member
  • **
  • Posts: 81
Re: Strange behavior after a drag and drop
« Reply #8 on: May 19, 2021, 12:02:37 pm »
Thanks for your help.
Just download the sample demo posted above from howardpc. Add a TButton (with the loop code) and a TMemo. Then move the panels and test the code. Both with Component and with Control the result is the same. The Panels are listed in the order of creation, i.e. the tag value is always sequential, from 0 to 4.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Strange behavior after a drag and drop
« Reply #9 on: May 19, 2021, 12:24:03 pm »
Ok, I see what you mean now.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Strange behavior after a drag and drop
« Reply #10 on: May 19, 2021, 12:31:30 pm »
Change the z-order using:
Code: Pascal  [Select][+][-]
  1.     ScrollBox1.SetControlIndex(sourcePnl, ScrollBox1.GetControlIndex(senderPnl));

In Howard's example project:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.PanelDragDrop(Sender, Source: TObject; X, Y: Integer);
  2. var
  3.   senderPnl: TPanel absolute Sender;
  4.   sourcePnl: TPanel absolute Source;
  5. begin
  6.   if (Sender is TPanel) and (Source is TPanel) then
  7.   begin
  8.     Exchange(senderPnl, sourcePnl);
  9.     ScrollBox1.SetControlIndex(sourcePnl, ScrollBox1.GetControlIndex(senderPnl));
  10.   end;
  11. end;

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Strange behavior after a drag and drop
« Reply #11 on: May 19, 2021, 12:36:51 pm »
You can also do a bit of extra work and discover the panel positions and sort (or at least order) references to the panels by position.
See RefreshSequenceDisplay() in the attached amended project.
« Last Edit: May 19, 2021, 07:41:06 pm by howardpc »

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Strange behavior after a drag and drop
« Reply #12 on: May 19, 2021, 01:36:30 pm »
Maybe a good solution would be to have an array of references to the panels. At the start they would be inserted in the default order (as in Form.Components) but it could be updated whenever a panel is dropped (as part of the process) to reflect the new order.

Basically, what you wish Components or Controls did, only you do it by hand O:-)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

valter.home

  • Jr. Member
  • **
  • Posts: 81
Re: Strange behavior after a drag and drop
« Reply #13 on: May 21, 2021, 06:00:23 pm »
Thanks guys, you helped me a lot.
The solution proposed by lucamar to use an array to be updated at each movement is actually the one I worked on from the beginning but the problem is that it would be necessary to check when the panel is released whether it is above or below a certain panel.
If the panel (source) were always above (or always below) the panel (sender) with a few lines of code it would be solved.
But also having to check if the panel (sender) has moved up or down compared to the panel it is moving the code would become much longer (at least for my ability).
I don't know if I have interpreted engkin's advice correctly but SetControlIndex should perhaps be applied to all panels after each change and it seems a bit laborious to me.
I then adapted howardpc's suggestion which works very well.
Thanks again to everyone.

« Last Edit: May 21, 2021, 06:05:43 pm by valter.home »

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: [SOLVED] Strange behavior after a drag and drop
« Reply #14 on: May 21, 2021, 06:37:06 pm »
Whatever solution works for you is fine.

I don't know if I have interpreted engkin's advice correctly but SetControlIndex should perhaps be applied to all panels after each change and it seems a bit laborious to me.

SetControlIndex takes care of the other panels.

 

TinyPortal © 2005-2018