### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: [Solved] how can change level of Align ??  (Read 9842 times)

#### majid.ebru

• Sr. Member
• Posts: 460
##### [Solved] how can change level of Align ??
« on: July 01, 2017, 10:37:32 am »
Hi

i put 3 panel(or an other element) in form.
then: (Photo 101)
Code: Pascal  [Select][+][-]
1. procedure TForm1.FormCreate(Sender: TObject);
2. begin
3.   Panel3.Align := alTop;
4.   Panel2.Align := alTop;
5.   Panel1.Align := alTop;
6. end;

after program runs, how can i change level of panel?(how can shift panels up or down)
like Photo 102  or Photo 103.

-----------------------------------------------------------------
an other question :

how can i set that one of panels(for example panel3) , always be top of all panels??

thank you
« Last Edit: July 01, 2017, 11:33:27 am by majid.ebru »

#### J-G

• Hero Member
• Posts: 942
##### Re: how can change level of Align ??
« Reply #1 on: July 01, 2017, 11:13:10 am »
Simply specify the 'Top' for each panel.

If the panel height is static (say 50) it is a simple matter to code :
Code: Pascal  [Select][+][-]
1.     procedure TForm1.FormCreate(Sender: TObject);
2.     begin
3.       Panel3.Top := 0;
4.       Panel2.Top := 51;
5.       Panel1.Top := 102;
6.     end;
7.

If the panel size is dynamic then a little more code is needed but it is only arithmatic.

To re-arrange, again just set the 'top' accordingly. If you want to avoid manual coding of the position throughout, just declare three constants :
Code: Pascal  [Select][+][-]
1. Const
2.   PanTop : byte = 0;
3.   PanMid : byte = 51;
4.   PanBot : byte = 102;
5.
6. procedure TForm1.FormCreate(Sender: TObject);
7. begin
8.    Panel2.Top := PanTop;
9.    Panel3.Top := PanMid;
10.    Panel1.Top := PanBot;
11. end;
12.
If the potential position is larger than 255 then simply declare the constants as word rather than byte.
« Last Edit: July 01, 2017, 11:24:07 am by J-G »
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0
Win 7 Ult 64

#### Handoko

• Hero Member
• Posts: 5045
• My goal: build my own game engine using Lazarus
##### Re: how can change level of Align ??
« Reply #2 on: July 01, 2017, 11:26:57 am »
Try my version.

Code: Pascal  [Select][+][-]
1. unit Unit1;
2.
3. {\$mode objfpc}{\$H+}
4.
5. interface
6.
7. uses
8.   Forms, Controls, ExtCtrls, StdCtrls;
9.
10. type
11.
12.   { TForm1 }
13.
14.   TForm1 = class(TForm)
15.     btnGreen: TButton;
16.     btnYellow: TButton;
17.     Button1: TButton;
18.     btnRed: TButton;
19.     pnlRed: TPanel;
20.     pnlGreen: TPanel;
21.     pnlYellow: TPanel;
22.     pnlBig: TPanel;
23.     procedure btnGreenClick(Sender: TObject);
24.     procedure btnRedClick(Sender: TObject);
25.     procedure btnYellowClick(Sender: TObject);
26.     procedure Button1Click(Sender: TObject);
27.   end;
28.
29. var
30.   Form1: TForm1;
31.
32. implementation
33.
34. {\$R *.lfm}
35.
36. { TForm1 }
37.
38. procedure TForm1.Button1Click(Sender: TObject);
39. begin
40.   Button1.Enabled := False;
41.   pnlRed.Align := alTop;
42.   pnlGreen.Align := alTop;
43.   pnlYellow.Align := alTop;
44.   btnRed.Enabled := True;
45.   btnGreen.Enabled := True;
46.   btnYellow.Enabled := True;
47. end;
48.
49. procedure TForm1.btnRedClick(Sender: TObject);
50. begin
51.   pnlRed.Top := 0;
52. end;
53.
54. procedure TForm1.btnYellowClick(Sender: TObject);
55. begin
56.   pnlYellow.Top := 0;
57. end;
58.
59. procedure TForm1.btnGreenClick(Sender: TObject);
60. begin
61.   pnlGreen.Top := 0;
62. end;
63.
64. end.

#### majid.ebru

• Sr. Member
• Posts: 460
##### Re: how can change level of Align ??
« Reply #3 on: July 01, 2017, 11:32:52 am »

@Handoko

it work very Gooood

thank you

#### majid.ebru

• Sr. Member
• Posts: 460
##### Re: [Solved] how can change level of Align ??
« Reply #4 on: July 01, 2017, 01:47:36 pm »
an other question :

for example i have 10 panels:

how can i rearrange panels like this:
.
1 - panel7 always be ontop and panel9 always be after it?
.
2 - level panel5 be 4?
.
3 - i put a TSpinEdit each panel and i want that level of panels equals with number of in TSpinEdit ?

#### Handoko

• Hero Member
• Posts: 5045
• My goal: build my own game engine using Lazarus
##### Re: [Solved] how can change level of Align ??
« Reply #5 on: July 01, 2017, 03:30:26 pm »
I don't fully understand, but I guess this is what you want:

Code: Pascal  [Select][+][-]
1. unit Unit1;
2.
3. {\$mode objfpc}{\$H+}
4.
5. interface
6.
7. uses
8.   Classes, Forms, Controls, Dialogs, StdCtrls, ExtCtrls;
9.
10. type
11.
12.   { TForm1 }
13.
14.   TForm1 = class(TForm)
15.     btnStart: TButton;
16.     btnProcess: TButton;
17.     cbbTop1: TComboBox;
18.     cbbTop2: TComboBox;
19.     cbbTop3: TComboBox;
20.     chbTop1: TCheckBox;
21.     chbTop2: TCheckBox;
22.     chbTop3: TCheckBox;
23.     pnlRed: TPanel;
24.     pnlGreen: TPanel;
25.     pnlYellow: TPanel;
26.     pnlAqua: TPanel;
27.     pnlWhite: TPanel;
28.     pnlBig: TPanel;
29.     procedure btnProcessClick(Sender: TObject);
30.     procedure btnStartClick(Sender: TObject);
31.     procedure cbbTop1Change(Sender: TObject);
32.     procedure cbbTop2Change(Sender: TObject);
33.     procedure cbbTop3Change(Sender: TObject);
34.     procedure chbTop1Change(Sender: TObject);
35.     procedure chbTop2Change(Sender: TObject);
36.     procedure chbTop3Change(Sender: TObject);
37.   end;
38.
39. var
40.   Form1: TForm1;
41.
42. implementation
43.
44. const
45.   // Each color have to assosiated with an index value
46.   indexRed    = 0;
47.   indexGreen  = 1;
48.   indexYellow = 2;
49.   indexAqua   = 3;
50.   indexWhite  = 4;
51.   // Total colors will be processed
52.   ColorsCount = 5;
53.
54. {\$R *.lfm}
55.
56. { TForm1 }
57.
58. procedure TForm1.btnStartClick(Sender: TObject);
59. var
60.   ColorNames: TStringList;
61.   i: Integer;
62. begin
63.   btnStart.Enabled := False;
64.
65.   pnlRed.Align    := alTop;
66.   pnlGreen.Align  := alTop;
67.   pnlYellow.Align := alTop;
68.   pnlAqua.Align   := alTop;
69.   pnlWhite.Align  := alTop;
70.
71.   chbTop1.Enabled := True;
72.   chbTop2.Enabled := True;
73.   chbTop3.Enabled := True;
74.
75.   // Get the name list based on sorted by index value of the colors
76.   ColorNames := TStringList.Create;
77.   for i := 0 to (ColorsCount-1) do
78.     case i of
84.     end;
85.
86.   // Put the names into all the comboboxes
87.   cbbTop1.Items := ColorNames;
88.   cbbTop2.Items := ColorNames;
89.   cbbTop3.Items := ColorNames;
90.
91.   // Delete ColorNames, because it is not needed anymore
92.   ColorNames.Free;
93.
94.   btnProcess.Enabled := True;
95. end;
96.
97. procedure TForm1.btnProcessClick(Sender: TObject);
98.   function ChoosePanelByColorIndex(ColorIndex: Integer): TPanel;
99.   begin
100.     case ColorIndex of
101.       indexRed    : Result := pnlRed;
102.       indexGreen  : Result := pnlGreen;
103.       indexYellow : Result := pnlYellow;
104.       indexAqua   : Result := pnlAqua;
105.       indexWhite  : Result := pnlWhite;
106.     end;
107.   end;
108. begin
109.   if (cbbTop3.ItemIndex >= 0) then
110.      ChoosePanelByColorIndex(cbbTop3.ItemIndex).Top := 0;
111.   if (cbbTop2.ItemIndex >= 0) then
112.      ChoosePanelByColorIndex(cbbTop2.ItemIndex).Top := 0;
113.   if (cbbTop1.ItemIndex >= 0) then
114.      ChoosePanelByColorIndex(cbbTop1.ItemIndex).Top := 0;
115. end;
116.
117. procedure TForm1.cbbTop1Change(Sender: TObject);
118. begin
119.   if (cbbTop1.ItemIndex = cbbTop2.ItemIndex) or
120.      (cbbTop1.ItemIndex = cbbTop3.ItemIndex) then
121.      begin
122.        ShowMessage('The color has been used by other ComboBox!');
123.        cbbTop1.Text := '< none >';
124.      end;
125. end;
126.
127. procedure TForm1.cbbTop2Change(Sender: TObject);
128. begin
129.   if (cbbTop2.ItemIndex = cbbTop1.ItemIndex) or
130.      (cbbTop2.ItemIndex = cbbTop3.ItemIndex) then
131.      begin
132.        ShowMessage('The color has been used by other ComboBox!');
133.        cbbTop2.Text := '< none >';
134.      end;
135. end;
136.
137. procedure TForm1.cbbTop3Change(Sender: TObject);
138. begin
139.   if (cbbTop3.ItemIndex = cbbTop1.ItemIndex) or
140.      (cbbTop3.ItemIndex = cbbTop2.ItemIndex) then
141.      begin
142.        ShowMessage('The color has been used by other ComboBox!');
143.        cbbTop3.Text := '< none >';
144.      end;
145. end;
146.
147. procedure TForm1.chbTop1Change(Sender: TObject);
148. begin
149.   cbbTop1.Enabled := chbTop1.Checked;
150.   if not(cbbTop1.Enabled) then cbbTop1.Text := '< none >';
151. end;
152.
153. procedure TForm1.chbTop2Change(Sender: TObject);
154. begin
155.   cbbTop2.Enabled := chbTop2.Checked;
156.   if not(cbbTop2.Enabled) then cbbTop2.Text := '< none >';
157. end;
158.
159. procedure TForm1.chbTop3Change(Sender: TObject);
160. begin
161.   cbbTop3.Enabled := chbTop3.Checked;
162.   if not(cbbTop3.Enabled) then cbbTop3.Text := '< none >';
163. end;
164.
165. end.

Panel that calls Top := 0 will always be the topmost. So if you want to sort several panels, for example having 3 panels on the top, you must do 3 times Top := 0 in backward order (lower to top) ... see line #109

To handle multiple panels easily, you need to associate an indexName (integer) with the panel:
indexRed, indexGreen, indexYellow, indexAqua, indexWhite

To know how to use indexName to refer the actual panel, see:
- const indexXXX   ... line #46
- var ColorNames   ... line #76
- function ChoosePanelByColorIndex   ... line #98
« Last Edit: July 01, 2017, 03:35:42 pm by Handoko »

#### majid.ebru

• Sr. Member
• Posts: 460
##### Re: [Solved] how can change level of Align ??
« Reply #6 on: July 01, 2017, 03:52:22 pm »
that's Great
.
sorry i can't enplane my question but you always understand( and answer to) my problem.
.
Thank you very much
.
for example :
.
this is  La Liga Table
.
i want to move row 10 (Eibar) to row 4 (Instead Sevilla) and all rows from row 4 goes down.
.
how can i do it??

#### Handoko

• Hero Member
• Posts: 5045
• My goal: build my own game engine using Lazarus
##### Re: [Solved] how can change level of Align ??
« Reply #7 on: July 01, 2017, 03:56:50 pm »
You need to use an extra item. Maybe TList, TFPList, manually create a singly link list or doubly link list or something like that.

Give me 10 minutes to write the example for you.

#### majid.ebru

• Sr. Member
• Posts: 460
##### Re: [Solved] how can change level of Align ??
« Reply #8 on: July 01, 2017, 04:00:28 pm »
Thank you

in your example if i don't select  top#2 and select top#3 then top#3 goes to level 2 ??

#### Handoko

• Hero Member
• Posts: 5045
• My goal: build my own game engine using Lazarus
##### Re: [Solved] how can change level of Align ??
« Reply #9 on: July 01, 2017, 04:29:44 pm »
No. Without using TList (or something similar) it is (almost) impossible.

I am still working on the example.

#### Handoko

• Hero Member
• Posts: 5045
• My goal: build my own game engine using Lazarus
##### Re: [Solved] how can change level of Align ??
« Reply #10 on: July 01, 2017, 06:17:42 pm »
You can try test3.zip.

To be able to store data, sort and retrieve them, you can use TList, TFPList, TObjectList, TFPObjectList, ... Read more here:
http://wiki.freepascal.org/Data_Structures,_Containers,_Collections

Which one should you use?
Each of them have their own advantages. For most cases TList is good enough. You can think TList is a more advanced version of array. You can do data sorting using array, but it will be much easier using TList:
https://www.freepascal.org/docs-html/rtl/classes/tlist.html

In my example, you can learn how to add data to a list, change its item's sorting position. I use a TMemo to show the result. If you want to do the panel sorting, just change the TList to link to TPanel. You can see from the code below, the TList is linked to TMyItem.

Code: Pascal  [Select][+][-]
1. unit Unit1;
2.
3. {\$mode objfpc}{\$H+}
4.
5. interface
6.
7. uses
8.   Classes, SysUtils, Forms, Controls, Dialogs, StdCtrls, ExtCtrls;
9.
10. type
11.
12.   { TForm1 }
13.
14.   TForm1 = class(TForm)
15.     btnStart: TButton;
16.     btnGenerate: TButton;
17.     btnMove: TButton;
18.     cbbFrom: TComboBox;
19.     cbbTo: TComboBox;
20.     Label1: TLabel;
21.     Label2: TLabel;
22.     Memo1: TMemo;
23.     Panel1: TPanel;
24.     procedure btnGenerateClick(Sender: TObject);
25.     procedure btnMoveClick(Sender: TObject);
26.     procedure btnStartClick(Sender: TObject);
27.     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
28.   public
29.     procedure ShowData;
30.   end;
31.
32.   TMyItem = record
33.     FirstName: string[10];
34.     LastName:  string[10];
35.     Phone:     string[10];
36.     Hobby:     string[10];
37.   end;
38.
39.   PMyItem = ^TMyItem;  //  <<<----- Pointer is needed for TList
40.
41. var
42.   Form1:  TForm1;
43.   MyData: TList; //  <<<----- TList is used store you data
44.
45. implementation
46.
47. {\$R *.lfm}
48.
49. { TForm1 }
50.
51. procedure TForm1.btnStartClick(Sender: TObject);
52. begin
53.   btnStart.Enabled := False;
54.   Panel1.Enabled   := True;
55.   MyData           := TList.Create;
56. end;
57.
58. procedure TForm1.btnGenerateClick(Sender: TObject);
59. var
60.   TempStorage: PMyItem;
61.   NewFirstname, NewLastName, NewPhone, NewHobby: string;
62.   ComboboxItems: TStringList;
63.   i: Integer;
64. begin
65.
66.   for i := 1 to 5 do
67.   begin
68.
69.     // Randomly choose a first name
70.     case Random(10) of
71.     0: NewFirstName := 'Amelia';
72.     1: NewFirstName := 'Harry';
73.     2: NewFirstName := 'Linda';
74.     3: NewFirstName := 'Charlie';
75.     4: NewFirstName := 'Tara';
76.     5: NewFirstName := 'Nicky';
77.     6: NewFirstName := 'Bob';
78.     7: NewFirstName := 'Lucy';
79.     8: NewFirstName := 'Tommy';
80.     9: NewFirstName := 'Susan';
81.     end;
82.
83.     // Randomly choose a last name
84.     case Random(10) of
85.     0: NewLastName := 'Brown';
86.     1: NewLastName := 'Strong';
87.     2: NewLastName := 'Jackson';
88.     3: NewLastName := 'Stone';
89.     4: NewLastName := 'Smith';
90.     5: NewLastName := 'Page';
91.     6: NewLastName := 'Parker';
92.     7: NewLastName := 'Lee';
93.     8: NewLastName := 'Wilson';
94.     9: NewLastName := 'Fox';
95.     end;
96.
97.     // Randomly generate a phone number
98.     NewPhone := IntToStr(Random(800000)+100000);
99.
100.     // Randomly choose a hobby
101.     case Random(10) of
102.     0: NewHobby := 'Singing';
103.     1: NewHobby := 'Painting';
104.     2: NewHobby := 'Travelling';
105.     3: NewHobby := 'Cooking';
106.     4: NewHobby := 'Cycling';
107.     5: NewHobby := 'Dancing';
108.     6: NewHobby := 'Writing';
109.     7: NewHobby := 'Shopping';
110.     8: NewHobby := 'Fishing';
111.     9: NewHobby := 'Watching';
112.     end;
113.
114.     // Add the new data to the list
115.     New(TempStorage);
116.     TempStorage^.FirstName := NewFirstname;
117.     TempStorage^.LastName  := NewLastName;
118.     TempStorage^.Phone     := NewPhone;
119.     TempStorage^.Hobby     := NewHobby;
120.     MyData.Add(TempStorage); // You can't add data to a list directly, you need to use a temp storage
121.
122.   end;
123.
124.   // Show the data on Memo1
125.   ShowData;
126.
127.   // Refresh the items inside the comboboxes
128.   ComboboxItems := TStringList.Create;
129.   for i := 1 to MyData.Count do ComboboxItems.Add(IntToStr(i));
130.   cbbFrom.Items := ComboboxItems;
131.   cbbTo.Items   := ComboboxItems;
132.   ComboboxItems.Free;
133.
134. end;
135.
136. procedure TForm1.btnMoveClick(Sender: TObject);
137. var
138.   TempData: PMyItem;
139. begin
140.
141.   if (cbbFrom.ItemIndex < 0) then
142.   begin
143.     ShowMessage('From cannot be empty!');
144.     Exit;
145.   end;
146.   if (cbbTo.ItemIndex < 0) then
147.   begin
148.     ShowMessage('To cannot be empty!');
149.     Exit;
150.   end;
151.   if (cbbFrom.ItemIndex = cbbTo.ItemIndex) then
152.   begin
153.     ShowMessage('From and To cannot be the same!');
154.     Exit;
155.   end;
156.
157.   // Save the 'From' data to a temporary pointer
158.   TempData := MyData.Items[cbbFrom.ItemIndex];
159.   // Delete the data from the list
160.   MyData.Delete(cbbFrom.ItemIndex);
161.   // Save the data back to the list
162.   MyData.Insert(cbbTo.ItemIndex, TempData);
163.
164.   // Show the result on Memo1
165.   ShowData;
166.
167. end;
168.
169. procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
170. begin
171.   MyData.Free;
172. end;
173.
174. procedure TForm1.ShowData;
175.   function MakeLeftString(const StrInput: string; StrLength: Byte): string;
176.   var
177.     S: string;
178.   begin
179.     S := StrInput;
180.     while (Length(S) < StrLength) do S := S + ' ';
181.     Result := S;
182.   end;
183.   function MakeRightString(const StrInput: string; StrLength: Byte): string;
184.   var
185.     S: string;
186.   begin
187.     S := StrInput;
188.     while (Length(S) < StrLength) do S := ' ' + S;
189.     Result := S;
190.   end;
191. var
192.   i: Integer;
193. begin
194.   Memo1.Clear;
196.       '    First Name Last Name  Phone      Hobby'             +' '+
197.       '-----------------------------------------------'
198.       );
199.   for i := 0 to (MyData.Count-1) do
201.       MakeRightString(IntToStr(i+1), 3)                       +' '+
202.       MakeLeftString(PMyItem(MyData.Items[i])^.FirstName, 10) +' '+
203.       MakeLeftString(PMyItem(MyData.Items[i])^.LastName, 10)  +' '+
204.       MakeLeftString(PMyItem(MyData.Items[i])^.Phone, 10)     +' '+
205.       MakeLeftString(PMyItem(MyData.Items[i])^.Hobby, 10)
206.       );
207. end;
208.
209. end.

Able to use TList will improve your programming skill a lot, so learn it seriously. You will use it a lot in your future.

Note:
The button "Generate 4 items" is not correct. It should be "Generate 5 items". It's my mistake.
« Last Edit: July 01, 2017, 06:29:14 pm by Handoko »

#### howardpc

• Hero Member
• Posts: 4144
##### Re: [Solved] how can change level of Align ??
« Reply #11 on: July 01, 2017, 11:51:34 pm »
this is  La Liga Table
.
i want to move row 10 (Eibar) to row 4 (Instead Sevilla) and all rows from row 4 goes down.

See the example attached.
« Last Edit: July 02, 2017, 10:49:33 am by howardpc »

#### Handoko

• Hero Member
• Posts: 5045
• My goal: build my own game engine using Lazarus
##### Re: [Solved] how can change level of Align ??
« Reply #12 on: July 02, 2017, 04:11:44 am »
Thank you for sharing different way to do the same thing.

It worked, but it also caused error.
To reproduce the error:

1. First select "2: Barcelona" then select "4. Sevilla"
2. Click "Change order"
3. Select "4: Sevilla" and then select "3. Atletico"
4. Click "Change order"

#### howardpc

• Hero Member
• Posts: 4144
##### Re: [Solved] how can change level of Align ??
« Reply #13 on: July 02, 2017, 10:56:18 am »
Indeed that project was flawed.
I was intending to show only how majid.ebru could reorder his list in the way he asked.
I don't recommend my project as a way to build a DIY database, even a simple one, hanging off a GUI container like TListbox.Items.
This was a quick hack to demonstrate a single idea.
However, for the sake of completeness I've posted a more robust example with a replaced project.

For database programming you are always best to start with a proper database, one that has already been well designed and debugged. My (second) example, while it illustrates a point using RAD, is not not a recommended way to approach database programming.

#### Handoko

• Hero Member
• Posts: 5045
• My goal: build my own game engine using Lazarus
##### Re: [Solved] how can change level of Align ??
« Reply #14 on: July 02, 2017, 04:44:57 pm »

I tried to learn the code, too difficult for me to understand. But what caught me attention was this:

Code: Pascal  [Select][+][-]
1.     if ListBox1.Selected[i] then begin
2.       case indexes[1] of
3.         -1: indexes[1]:=PtrInt(ListBox1.Items.Objects[i]);
4.         else case indexes[2] of
5.                -1: indexes[2]:=PtrInt(ListBox1.Items.Objects[i]);
6.                else Break;
7.              end;
8.       end;
9.     end;

It seems to be a new trick to me. You used "case of" instead of if-them-else. Please explain, why you didn't use if-them-else?