Recent

Author Topic: [SOLVED] Problem with component design.  (Read 677 times)

pcurtis

  • Hero Member
  • *****
  • Posts: 951
[SOLVED] Problem with component design.
« on: October 02, 2020, 11:02:43 am »
Hi All,
I am continuing to play with designing a simple component and have come upon a problem.

The component is based on TCustomControl and uses a TShape and I have created a property - Pen so I can change the shape.

In design time changes to the Pen do not show on the component.

If I create the component at runtime changes to individual Pen attributes do not show on the component, but if I change the complete Pen object the component changes.

Any ideas?

Thanks in advance.
« Last Edit: October 02, 2020, 12:19:01 pm by pcurtis »
Windows 10 20H2
Laz 2.2.0
FPC 3.2.2

wp

  • Hero Member
  • *****
  • Posts: 11857
Re: Problem with component design.
« Reply #1 on: October 02, 2020, 11:42:23 am »
I think there is a conflict between your component's Pen and the Pen of the Shape. Why do you need two? Why don't you simply publish the Shape's Pen as the component's Pen? I did not check the designtime issue, but this solves at least the runtime issue.

Code: Pascal  [Select][+][-]
  1.   TMyLED2 = class(TCustomControl)
  2.   private
  3.     fTimer : TTimer;
  4.     fShape : TShape;
  5.     fPulseInterval : integer;
  6.     fOnColor : TColor;
  7.     fOffColor : TColor;
  8.     fShapeType : TShapeType;
  9. //    fPen : TPen;                            // <------------------ REMOVE
  10.     function GetPulseInterval : integer;
  11.     procedure SetPulseInterval(Value : integer);
  12.     function GetOnColor : TColor;
  13.     procedure SetOnColor(Value : TColor);
  14.     function GetOffColor : TColor;
  15.     procedure SetOffColor(Value : TColor);
  16.     function GetShapeType : TShapeType;
  17.     procedure SetShapeType(Value : TShapeType);
  18.     function GetPen : TPen;
  19.     procedure SetPen(Value : TPen);
  20.   protected
  21.     procedure MyTimer(Sender: TObject);
  22.   public
  23.     constructor Create(AOwner : TComponent); override;
  24.     procedure Pulse;
  25.   published
  26.     property Pen : TPen read GetPen write SetPen;
  27.     property Shape : TShapeType read GetShapeType write SetShapeType;
  28.     property PulseInterval : integer read GetPulseInterval write SetPulseInterval;
  29.     property OnColor : TColor read GetOnColor write SetOnColor;
  30.     property OffColor : TColor read GetOffColor write SetOffColor;
  31.   end;  
  32.  
  33. constructor TMyLED2.Create(AOwner : TComponent);
  34. begin
  35.   inherited Create(AOwner);
  36.  
  37.   fPulseInterval := 100;
  38.   fOnColor := clLime;
  39.   fOffColor := clBlue;
  40.   fShapeType := stRectangle;
  41.  
  42. //  fPen := TPen.Create;                     // <--------------- REMOVE
  43.  
  44.   Width := 50;
  45.   Height := 50;
  46.  
  47.   fTimer := TTimer.Create(self);
  48.   with fTimer do
  49.   begin
  50.     Enabled := false;
  51.     Interval := fPulseInterval;
  52.     OnTimer := @MyTimer;
  53.   end;
  54.  
  55.   fShape := TShape.Create(self);
  56.   with fShape do
  57.   begin
  58.     Align := alClient;
  59.     Shape := fShapeType;
  60.     Parent := self;
  61.     Brush.Color := fOffColor;
  62.   end;
  63.  
  64.   //Constraints.MaxHeight := 23;
  65.   Constraints.MinHeight := 10;
  66.   //Constraints.MaxWidth := 23;
  67.   Constraints.MinWidth := 10;
  68.   //SetBounds(0, 0, 20, 20);
  69. end;
  70.  
  71. function TMyLED2.GetPen : TPen;
  72. begin
  73.   // result := fPen;                      // <------------- use the Shape's Pen
  74.   result := FShape.Pen;
  75. end;
  76.  
  77. procedure TMyLED2.SetPen(Value : TPen);
  78. begin
  79. //  If fPen <> Value then                 // <--------------- use the Shape's Pen
  80.   if GetPen <> Value then
  81.     begin
  82. //      fShape.Pen := fPen;
  83.       fShape.Pen.Assign(Value);
  84.     end;
  85. end;

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Problem with component design.
« Reply #2 on: October 02, 2020, 11:59:01 am »
Because you did not provide the lpk file, I treated your source as a common unit and made some necessary changes to be able to use it. And then it works:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, StdCtrls, ExtCtrls, myled2;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     Button2: TButton;
  17.     procedure Button1Click(Sender: TObject);
  18.     procedure Button2Click(Sender: TObject);
  19.     procedure FormCreate(Sender: TObject);
  20.   private
  21.     aLED: TMyLED2;
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. { TForm1 }
  32.  
  33. procedure TForm1.Button1Click(Sender: TObject);
  34. begin
  35.   aLED.Pulse;
  36. end;
  37.  
  38. procedure TForm1.Button2Click(Sender: TObject);
  39. var
  40.   aPen: TPen;
  41. begin
  42.   aPen := aLED.Pen;
  43.   aPen.Color := Random($FFFFFF);
  44.   aPen.Width := Random(10);
  45. end;
  46.  
  47. procedure TForm1.FormCreate(Sender: TObject);
  48. begin
  49.   aLED := TMyLED2.Create(Self);
  50. end;
  51.  
  52. end.

Because fShape already has pen property, you do not need to create a new pen.

Code: Pascal  [Select][+][-]
  1. function TMyLED2.GetPen : TPen;
  2. begin
  3.   result := fShape.Pen;
  4. end;
  5.  
  6. {
  7. procedure TMyLED2.SetPen(Value : TPen);
  8. begin
  9.   If fPen <> Value then
  10.     begin
  11.       fPen := Value;
  12.       fShape.Pen := fPen;
  13.     end;
  14. end;
  15. }

Oh, I'm late. It already answered by wp.

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Problem with component design.
« Reply #3 on: October 02, 2020, 12:07:05 pm »
Code: Pascal  [Select][+][-]
  1. procedure TMyLED2.SetPen(Value : TPen);
  2. begin
  3. //  If fPen <> Value then                 // <--------------- use the Shape's Pen
  4.   if GetPen <> Value then
  5.     begin
  6. //      fShape.Pen := fPen;
  7.       fShape.Pen.Assign(Value);
  8.     end;
  9. end;

It is better if the old pen being freed before or maybe after assigning the shape to a new pen?

pcurtis

  • Hero Member
  • *****
  • Posts: 951
Re: Problem with component design.
« Reply #4 on: October 02, 2020, 12:18:04 pm »
Job done. Thanks both.
Windows 10 20H2
Laz 2.2.0
FPC 3.2.2

 

TinyPortal © 2005-2018