Recent

Author Topic: TWSButton descendance  (Read 1713 times)

lagprogramming

  • Sr. Member
  • ****
  • Posts: 407
TWSButton descendance
« on: December 01, 2023, 02:29:19 pm »
I have a patch that fixes custom-drawn's TButton's empty caption but there is an issue. I've looked at lcl/widgetset/wsstdctrls.pp and I've noticed the following lines:

Code: Pascal  [Select][+][-]
  1.   TWSButtonControl = class(TWSWinControl)
  2.   published
  3.     class function GetDefaultColor(const AControl: TControl; const ADefaultColorType: TDefaultColorType): TColor; override;
  4.   end;
  5.  
  6.   { TWSButton }
  7.  
  8.   TWSButton = class(TWSButtonControl)
  9.   published
  10.     class procedure SetDefault(const AButton: TCustomButton; ADefault: Boolean); virtual;
  11.     class procedure SetShortCut(const AButton: TCustomButton; const ShortCutK1, ShortCutK2: TShortCut); virtual;
  12.   end;
  13.   TWSButtonClass = class of TWSButton;
  14.  
  15.   { TWSCustomCheckBox }
  16.  
  17.   TWSCustomCheckBox = class(TWSButtonControl)
  18.   published
  19.     class function  RetrieveState(const ACustomCheckBox: TCustomCheckBox): TCheckBoxState; virtual;
  20.     class procedure SetShortCut(const ACustomCheckBox: TCustomCheckBox; const ShortCutK1, ShortCutK2: TShortCut); virtual;
  21.     class procedure SetState(const ACustomCheckBox: TCustomCheckBox; const NewState: TCheckBoxState); virtual;
  22.     class procedure SetAlignment(const ACustomCheckBox: TCustomCheckBox; const NewAlignment: TLeftRight); virtual;
  23.   end;
  24.   TWSCustomCheckBoxClass = class of TWSCustomCheckBox;
  25.  
  26.   { TWSCheckBox }
  27.  
  28.   TWSCheckBox = class(TWSCustomCheckBox)
  29.   published
  30.   end;
  31.  
 
Notice that as an example, TWSCheckBox is a descendant of TWSCustomCheckBox, but TWSButton is not a descendant of a TWSCustomButton.
Code: Pascal  [Select][+][-]
  1.   TWSEdit = class(TWSCustomEdit)
  2.   published
  3.   end;
  4.  
  5.   { TWSMemo }
  6.  
  7.   TWSMemo = class(TWSCustomMemo)
  8.   published
  9.   end;
TWSMemo is a descendant of TWSCustomMemo, TWSEdit of TWSCustomEdit, and so on. It's TWSButton the one that looks out of ordinary.
Isn't this a bug in LCL:-\ Shouldn't TWSButton have been a descendant of TWSCustomButton where TWSCustomButton would have been a descendant of TWSButtonControl, like TWSCheckBox is?

lagprogramming

  • Sr. Member
  • ****
  • Posts: 407
Re: TWSButton descendance
« Reply #1 on: December 07, 2023, 09:07:36 am »
I'm still looking forward for an answer.
Maybe an experienced LCL developer can explain why TWSButton isn't a descendant of TWSCustomButton.

zeljko

  • Hero Member
  • *****
  • Posts: 1668
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: TWSButton descendance
« Reply #2 on: December 07, 2023, 05:18:24 pm »
Maybe bug from the beginning of WS. Maybe Mattias or Marc know exact reason for this.

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2615
Re: TWSButton descendance
« Reply #3 on: December 08, 2023, 11:49:41 am »
I don't recall why, but I think the main reason is that a WS custom is not of much use. The WS has to implement the "real thing" and not some abstract control. So if you want to derive your control from a custom control, you want specific features which have to be available in the widgetsets too. So in most cases you need a specific WS class as well.
The fact that there exist TWSCustom classes might be that they have been added later either simply as counterpart of the LCL one, or that there indeed was a shared piece of functionality
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10557
  • Debugger - SynEdit - and more
    • wiki
Re: TWSButton descendance
« Reply #4 on: December 08, 2023, 12:54:13 pm »
The question is, does it cause a problem? And if so, what problem.

TCustomSomething is usually the implementation of Something, and TSomething only publishes the relevant properties => that is so you can have a T[Custum]SpecialSomething, which does not publish all the properties that TSomething published.

But in the TWS.... classes, there is no such thing as publishing properties. (there is published, but not sure why... where it is used / there should be no need to un-publish).

So as pointed out, the TWS... classes usually do not need that distinction.

It seems that for many classes they have been added. If really matters to you why, then use git blame to see when (and maybe if mentioned in commit message: why) they were added. Or maybe they were added in the beginning, and eventually it was realized that there was no need.

That said, the way WS classes work has at times been misunderstood, and there could be commits that are tainted by that.


In any case, I would classify it as: If it ain't broke, ...

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10557
  • Debugger - SynEdit - and more
    • wiki
Re: TWSButton descendance
« Reply #5 on: December 08, 2023, 12:58:46 pm »
I do say however it should probably be renamed to TWSCustomButton, and then there needs to be no TWSButton.

After all, it is registered by/for the TCustomButton
Code: Pascal  [Select][+][-]
  1. function RegisterCustomButton: Boolean; alias : 'WSRegisterCustomButton';
  2. begin
  3.   RegisterWSComponent(TCustomButton, TWin32WSButton);
  4.   Result := True;
  5. end;
  6.  

Whereas TButton itself does not register anything. So no need for a TWsButton.

lagprogramming

  • Sr. Member
  • ****
  • Posts: 407
Re: TWSButton descendance
« Reply #6 on: December 09, 2023, 11:06:40 am »
The question is, does it cause a problem? And if so, what problem.
The point is to have a single idiom, if possible. It's hard to learn and especially to debug something big as the LCL when objects that should behave similar have unnecessary different code implementations. In this example, using linux-customdrawn, I put a button on a form and a bitbtn. The TButton doesn't show it's caption, the TBitbtn shows it. I look at the code to see what's different at TButton in comparison with TBitbtn. After seeing what code looks simmilar and what's different I start having additional questions. So I compare the code of the buttons with the code of other objects that work fine and I start noticing some idioms. I learn from those idioms but because TWSButton is not a descendant of TWSCustombutton, the code looks a bit different so I start having additional questions. These additional questions can be avoided if a single idiom would have been used. In this particular example, if TWSButton would have been a descendant of TWSCustomButton, because it would follow the same idiom used when implementing objects like TWSCheckBox(which is a descendant of TWSCustomCheckBox), TWSEdit(which is a descendant of TWSCustomEdit) or TWSMemo(which is a descendant of TWSCustomMemo).
Anyway, I'll present a patch for fixing the TButton caption in a different forum post, patch that would modify as little code as possible.

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2615
Re: TWSButton descendance
« Reply #7 on: December 14, 2023, 08:54:05 am »

But in the TWS.... classes, there is no such thing as publishing properties. (there is published, but not sure why... where it is used / there should be no need to un-publish).


IIRC,
At runtime the class hierarchy of the WS classes is modified. The specific WS implementation classes are inserted in the hierarchy. To be able to do this, virtual methods need to be resolved. RTTI is needed for that and is only available for published members.

NOTE: This mechanism is made before the fpc 1.0 times.  If at that time interfaces would have worked reliable, I would have used that.
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

 

TinyPortal © 2005-2018