Recent

Author Topic: Component with properties renamed  (Read 3945 times)

peshte

  • New Member
  • *
  • Posts: 13
Component with properties renamed
« on: July 22, 2016, 10:24:33 am »
Hi.

I need to create a component derived from an LCL component, but with some properties rename.

Something like this:

uses Buttons;

type
  TMyButton= class(TSpeedButton)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
    property Text read Caption write Caption;
  end;

The property Text will replace the property Caption of the original component. But this code can not compile:
Error: Unknown class field or method identifier "Caption"

Any suggestions?

Leledumbo

  • Hero Member
  • *****
  • Posts: 8262
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Component with properties renamed
« Reply #1 on: July 22, 2016, 10:40:37 am »
Properties should be mapped to either fields or methods, not another properties. FCaption is what you're looking for (assuming it's accessible).

Thaddy

  • Hero Member
  • *****
  • Posts: 10436
Re: Component with properties renamed
« Reply #2 on: July 22, 2016, 11:08:21 am »
It is also perfectly legal to add a property and use the same getter and setter as already defined for another property.
Also note visual components are often derived from a TCustomXXX which in many cases just not publishes properties.
If that is the case you can add a property whith a different name in your derived component and publish that instead of - in this case - caption and use the access methods that are defined for caption: either FCaption directly or the get and/or set methods.

The other option is to write a getter and setter that accesses the caption property. That is legal:
Code: Pascal  [Select][+][-]
  1. type
  2.   TMyButton= class(TSpeedButton)
  3.   private
  4.     { Private declarations }
  5.   protected
  6.     { Protected declarations }
  7.      function GetTheRealCaption:String;  // here it is legal to return the caption property
  8.      procedure SetTheRealCaption(aString:string); // here it is legal to set the real caption property instead if the field...
  9.   public
  10.     { Public declarations }
  11.   published
  12.     { Published declarations }
  13.     property Text read GetTheRealCaption write SetTheRealCaption;
  14.   end;
  15.  

If you want that? You've got it.
I do not recommend it, though....
« Last Edit: July 22, 2016, 11:17:01 am by Thaddy »
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

Thaddy

  • Hero Member
  • *****
  • Posts: 10436
Re: Component with properties renamed
« Reply #3 on: July 22, 2016, 11:22:41 am »
Oh and by the way: the reason for the TCustomXXX ancestors is originally that you can not UN-publish properties.
So look if there is a TCustomSpeedButton.

In commercial products - written in a team - I always go for that option to prevent team members including myself making mistakes and introducing bugs.
(In fact I always design components to have an unpublishing TCustomxxx ancestor)
« Last Edit: July 22, 2016, 11:32:02 am by Thaddy »
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

peshte

  • New Member
  • *
  • Posts: 13
Re: Component with properties renamed
« Reply #4 on: July 23, 2016, 07:46:59 am »
I do not recommend it, though....
Why is that?

It worked with GetTheRealCaption and SetTheRealCaption. I just declare property Text:string, first.
Thanks.

However, is there a simplest method to rewrite that property?
FCaption does not exists in TSpeedButton.


Thaddy

  • Hero Member
  • *****
  • Posts: 10436
Re: Component with properties renamed
« Reply #5 on: July 23, 2016, 09:49:32 am »
That is because ultimately TSpeedbutton derives from TControl.
In TControl there is a protected property Caption.

I believe the get/set methods are GetText and SetText.
It is always better to use these methods to Access your renamed property so you do not add extra methods.
Code: Pascal  [Select][+][-]
  1. property Text:string read GetText write SetText; //these are already implemented for you!
 

Try that first (it works under Delphi) and see if it also works in Lazarus... ;)
« Last Edit: July 23, 2016, 09:57:32 am by Thaddy »
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

Thaddy

  • Hero Member
  • *****
  • Posts: 10436
Re: Component with properties renamed
« Reply #6 on: July 23, 2016, 11:03:06 am »
It should be even easier than the above, because in Delphi TControl has a protected property Text that have the same getter and setter as Caption.
So if Lazarus follows the same architecture as Delphi this code is enough;
Code: Pascal  [Select][+][-]
  1. type
  2.   TMyButton = class(TSpeedbutton)
  3.   published
  4.     property Text;  // promote visibility from protected to published....
  5.   end;
  6.  

Nothing more...
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

peshte

  • New Member
  • *
  • Posts: 13
Re: Component with properties renamed
« Reply #7 on: July 24, 2016, 11:20:51 am »
Hmm...yes, it works with just property Text;
But I will use the other ways for other components that don't work this way.


Now, I am trying to map property "width" to "size.width".
As what I found, it must look something like this:

TSize=class(TPersistent)
    public
      Width:integer;
      Height:integer;
  end;

TMyButton = class(TSpeedButton)
  private
    { Private declarations }
  protected
    { Protected declarations }
    function ReadSize:TSize;
    procedure WriteSize(ASize:TSize);
  public
    { Public declarations }

  published
    { Published declarations }
    property Text;
    property Size:TSize read ReadSize write WriteSize;
  end;

...implementation...

function TMyButton.ReadSize:TSize;
begin
  Result.Width:=Self.Width;
  Result.Height:=self.Height;
end;

procedure TMyButton .WriteSize(ASize:TSize);
begin
  self.Width:=ASize.Width;
  Self.Height:=ASize.Height;
end;

I've tryed to declare TSize as class and record too.

Thaddy

  • Hero Member
  • *****
  • Posts: 10436
Re: Component with properties renamed
« Reply #8 on: July 24, 2016, 12:12:01 pm »
Look for property BoundsRect:TRect;
« Last Edit: July 24, 2016, 12:14:44 pm by Thaddy »
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

 

TinyPortal © 2005-2018