Monday, 30 July 2018
Delphi - Sort an Object List by Property
Below is a quick example of how to use the .Sort function. In this case i have two objects declared in the Type seciton. On form create i am creating an instance of TPersons, then creating a number of dummy TPersons and adding them to my 'Persons'. Then behind a button click i am sorting the order of the Persons using the following code:
Persons.Sort(TComparer<TPerson>.Construct(
function (const L,R: TPerson): integer
begin
if L.Name > R.Name then
Result := 1
else if L.Name < R.Name then
Result := -1
else
Result := 0;
end
));
end;
To recreate this simple example, drop a memo and a button on a form. The make your code look like this:
unit Unit2;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls, Generics.Collections, FMX.ScrollBox,
FMX.Memo, Generics.Defaults;
type
TForm2 = class(TForm)
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TPerson = class(TObject)
Name: string;
Age: integer;
end;
TPersons = class(TObjectList<TPerson>)
end;
var
Form2: TForm2;
implementation
{$R *.fmx}
var
Persons: TPersons;
procedure TForm2.Button1Click(Sender: TObject);
var
Person: TPerson;
I: Integer;
begin
for Person in Persons do
begin
Persons.Sort(TComparer<TPerson>.Construct(
function (const L,R: TPerson): integer
begin
if L.Name > R.Name then
Result := 1
else if L.Name < R.Name then
Result := -1
else
Result := 0;
end
));
end;
for I := 0 to Persons.Count -1 do
begin
Memo1.Lines.Add(Persons[I].Name);
end;
end;
procedure TForm2.FormCreate(Sender: TObject);
var
Person: TPerson;
I: Integer;
begin
Persons := TPersons.Create(true);
Person := TPerson.Create;
Person.Name := 'John';
Person.Age := 34;
Persons.Add(Person);
Person := TPerson.Create;
Person.Name := 'James';
Person.Age := 31;
Persons.Add(Person);
Person := TPerson.Create;
Person.Name := 'Sally';
Person.Age := 21;
Persons.Add(Person);
end;
procedure TForm2.FormDestroy(Sender: TObject);
begin
Persons.Free;
end;
end.
Monday, 23 July 2018
Delphi FMX/Firemonkey - Fill a Rect/RoundRect/Ellipse with a Image/Bitmap
Here is a simple example of how to fill a given shape (TRectangle, TRoundRect, TEllipse etc) with the bitmap which belongs to an image. In this example i have created a new project, dropped a button and an RoundRect onto the form. On the Button Click i have the following code:
procedure TForm1.Button1Click(Sender: TObject);
var
Image: TImage;
begin
Image := TImage.Create(self);
Image.Bitmap.LoadFromFile('C:\Temp\Test.jpg');
RoundRect1.Fill.Kind := TbrushKind.Bitmap;
RoundRect1.Fill.Bitmap.WrapMode := TWrapMode.TileStretch;
RoundRect1.Fill.Bitmap.Bitmap := Image.Bitmap;
end;
This will create a new instance of a TImage. Load my Test.jpg file into its Bitmap property. Then set the Image to fill the space in the RoundRect.
procedure TForm1.Button1Click(Sender: TObject);
var
Image: TImage;
begin
Image := TImage.Create(self);
Image.Bitmap.LoadFromFile('C:\Temp\Test.jpg');
RoundRect1.Fill.Kind := TbrushKind.Bitmap;
RoundRect1.Fill.Bitmap.WrapMode := TWrapMode.TileStretch;
RoundRect1.Fill.Bitmap.Bitmap := Image.Bitmap;
end;
This will create a new instance of a TImage. Load my Test.jpg file into its Bitmap property. Then set the Image to fill the space in the RoundRect.
Thursday, 19 July 2018
Delphi - Set Font Property of a Component in Firemonkey/FMX
In order to set the font property of a component in FMX there are two ways you can do it:
1) In design time. By dropping a component onto the form and then changing its properties in the Object Inspector you can alter the properties of the font (font fmaily, size, color etc).
2) At run time. If, for example, you have a project which drops a series of labels onto a form when a button is clicked then you'll need to handle the changing of the font in your code.
Option 1 is pretty straight forward but it's worth noting that if you make this change, you can view the effect this has had by saving your project and then opening up the .fmx file in notedpad and looking to see what has changed. In my project, i added a label to my form and changed the Text Settings > Font Color to be 'crimson'. In my .fmx file i can see that there are now two new lines:
object Label1: TLabel
Position.X = 120.000000000000000000
Position.Y = 352.000000000000000000
TextSettings.FontColor = claCrimson
StyledSettings = [Family, Size, Style]
Text = 'Label1'
end
This shows us what the impact was of changing the font color. The first change is to be expected since the property we changed was the FontColor. The second change is important, however, since it shows us what other change delphi made under the covers - namely that delphi altered the StyledSettings. The styled settings tell delphi whether to pull down the projects style settings (i.e. those which may be applied through a stylebook) for a given setting. Thus if you go back to design time and drop down the StyledSettings option, you'll see that 'FontColor' is currently unchecked. If you check the box against it, the font in the label will cease to be red.
Thus, if you're creating new components at run time and need to alter some property of the font style, you'll need to include two lines - one to set the font setting and one to uncheck the relevant setting in StyledSettings:
MyLabel.TextSettings.FontColor := TAlphaColor($FF009900);
MyLabel.StyledSettings := [TStyledSetting.Family, TStyledSetting.Size, TStyledSetting.Style];
1) In design time. By dropping a component onto the form and then changing its properties in the Object Inspector you can alter the properties of the font (font fmaily, size, color etc).
2) At run time. If, for example, you have a project which drops a series of labels onto a form when a button is clicked then you'll need to handle the changing of the font in your code.
Option 1 is pretty straight forward but it's worth noting that if you make this change, you can view the effect this has had by saving your project and then opening up the .fmx file in notedpad and looking to see what has changed. In my project, i added a label to my form and changed the Text Settings > Font Color to be 'crimson'. In my .fmx file i can see that there are now two new lines:
object Label1: TLabel
Position.X = 120.000000000000000000
Position.Y = 352.000000000000000000
TextSettings.FontColor = claCrimson
StyledSettings = [Family, Size, Style]
Text = 'Label1'
end
This shows us what the impact was of changing the font color. The first change is to be expected since the property we changed was the FontColor. The second change is important, however, since it shows us what other change delphi made under the covers - namely that delphi altered the StyledSettings. The styled settings tell delphi whether to pull down the projects style settings (i.e. those which may be applied through a stylebook) for a given setting. Thus if you go back to design time and drop down the StyledSettings option, you'll see that 'FontColor' is currently unchecked. If you check the box against it, the font in the label will cease to be red.
Thus, if you're creating new components at run time and need to alter some property of the font style, you'll need to include two lines - one to set the font setting and one to uncheck the relevant setting in StyledSettings:
MyLabel.TextSettings.FontColor := TAlphaColor($FF009900);
MyLabel.StyledSettings := [TStyledSetting.Family, TStyledSetting.Size, TStyledSetting.Style];
Monday, 9 July 2018
Delphi - Load Image From Project Resource (FMX) - Simple Example
For this example i have a created a new FMX (firemonkey) form. I have added a button and an image onto the. I have then gone to Project > Resources and Images, and loaded in a bitmap image. I have set:
Resource Identifier: 'Bitmap_1'.
Resource Type: 'RCDATA'
Back on my form i have double clicked on the button and behind the button click put the code to instantiate a resource stream, load the image into it, assign it to a bitmap and then set it to be the image on the form.
unit Unit2;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects,
FMX.Controls.Presentation, FMX.StdCtrls;
type
TForm2 = class(TForm)
Image1: TImage;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.fmx}
procedure TForm2.Button1Click(Sender: TObject);
var
B: TBitmap;
RS: TResourceStream;
begin
RS := TResourceStream.Create(HInstance, 'Bitmap_1', RT_RCDATA);
try
B := TBitmap.Create;
B.LoadFromStream(RS);
Image1.Bitmap := B;
finally
RS.Free;
end;
end;
end.
Resource Identifier: 'Bitmap_1'.
Resource Type: 'RCDATA'
Back on my form i have double clicked on the button and behind the button click put the code to instantiate a resource stream, load the image into it, assign it to a bitmap and then set it to be the image on the form.
unit Unit2;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects,
FMX.Controls.Presentation, FMX.StdCtrls;
type
TForm2 = class(TForm)
Image1: TImage;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.fmx}
procedure TForm2.Button1Click(Sender: TObject);
var
B: TBitmap;
RS: TResourceStream;
begin
RS := TResourceStream.Create(HInstance, 'Bitmap_1', RT_RCDATA);
try
B := TBitmap.Create;
B.LoadFromStream(RS);
Image1.Bitmap := B;
finally
RS.Free;
end;
end;
end.
Subscribe to:
Posts (Atom)