2
votes

What did I do?

I'm trying to develop a FMX Gauge component. For the time being it has only a needle. I've created a new Package and added the following code: unit FMX.VDO;

interface

uses
    System.SysUtils,
    System.Classes,
    FMX.Types,
    FMX.Controls,
    FMX.MultiResBitmap,
    FMX.Layouts,
    FMX.Objects;

type
    TVdoLayout = class(TScaledLayout)
    private        
        FNeedle    : TImage;

        function GetBitMapNeedle: TFixedMultiResBitmap;        
        procedure SetBitMapNeedle(const Value: TFixedMultiResBitmap);
        function GetValue: Double;
        procedure SetValue(const Value: Double);        
        { Private declarations }

    protected
        { Protected declarations }
    public
        { Public declarations }
        constructor Create(AOwner: TComponent); override;
    published
        { Published declarations }        
        property BitMapNeedle    : TFixedMultiResBitmap read GetBitMapNeedle write SetBitMapNeedle;
        property Value           : Double read GetValue write SetValue;
    end;

procedure Register;

implementation

procedure Register;
begin
    RegisterComponents('Samples', [TVdoLayout]);
end;

{ TVdoLayout }

constructor TVdoLayout.Create(AOwner: TComponent);
begin
    inherited;
    Self.Size.Width  := 326;
    Self.Size.Height := Self.Size.Width;

    FNeedle                  := TImage.Create(Self);
    FNeedle.Parent           := Self;
    FNeedle.Width            := 262;
    FNeedle.Height           := 21;
    FNeedle.Position.X       := 40;
    FNeedle.Position.Y       := 270;
    FNeedle.Height           := Self.Height * 0.04901;
    FNeedle.Width            := Self.Width * 0.7485;
    FNeedle.RotationCenter.X := 0.935;
    FNeedle.RotationCenter.Y := 0.27;

    FNeedle.RotationAngle := 45;
end;    

function TVdoLayout.GetBitMapNeedle: TFixedMultiResBitmap;
begin
    Result := FNeedle.MultiResBitmap;
end;

procedure TVdoLayout.SetBitMapNeedle(const Value: TFixedMultiResBitmap);
begin    
    FNeedle.MultiResBitmap := Value;
end;

function TVdoLayout.GetValue: Double;
begin
    Result := FNeedle.RotationAngle;
end;    

procedure TVdoLayout.SetValue(const Value: Double);
begin    
    FNeedle.RotationAngle := Value;    
end;

end.

After this I've build the project and installed my component.

I've created a new FMX project and put my component. I load a picture of a needle in design time. See below:

Needle design time

At design time I can change the property Value. If you see the code above, Value changes RotationAngle of the needle. It works perfectly at design time.

What's the problem?

In run time, when I change the Value property of my component through TEdit to 90 it works, but a snapshot of the initial needle is taken, and it seems duplicate as can be seen below:

Needle run time

Other things that I've tried without success?

I've tried to call resize and repaint functions. Also added FNeedle.SetSubComponent(True); during Create as @UweRaabe suggested. If I load the needle image at run time it works. But this is not a desirable solution.

Details

  • Delphi 10.1 Berlin
  • FireMonkey (on Windows)
1
You are probably tricked by the streaming system. Does it work when you add FNeedle.SetSubComponent(True) during Create?Uwe Raabe
@UweRaabe No, it doesn't.Daniel Grillo
In that case please provide a minimal project showing the error.Uwe Raabe
@UweRaabe, I reformulated my question. I think now it's easier to reproduce.Daniel Grillo
When you made the test with SetSubComponent, did you re-create your DFM or did you test with the existing one?Uwe Raabe

1 Answers

1
votes

In my searches I found the solution here: Firemonkey: How to define a component that contain another component?

I have just to set the property Stored as False. See below:

FNeedle.Stored := false;