[Lazarus] TCustomNotebook

Hans-Peter Diettrich DrDiettrich1 at aol.com
Wed Jul 6 19:26:54 CEST 2011


Please let's continue the discussion here, not in Mantis.

Obviously we differ very much in our concepts, so that we should either 
come to a consent, or leave everything as bad as is.

Felipe Monteiro de Carvalho schrieb:

> General concepts:
> 1> Avoid changing the current TPageControl as much as possible,
> because it is extensively used and changes here might cause a pletora
> of problems
> 2> I think it is no problem to introduce heavy changes to TTabControl
> because it is rarely used
> 3> Use exactly the same class hierarchy as Delphi:
> 
> TCustomNotebook (in Delphi called TCustomTabControl)
> --> TPageControl
> --> TTabControl

This hierarchy would require to make the widgetsets independent from 
specialized Pages (TCustomPage descendants), and this is just what I 
have in mind.

> Just because this hard distinction of a control with pages and one
> without makes sense in Windows it doesn't mean at all that it makes
> sense in all widgetsets. Plus, just 1 implementation is better then 2
> spread across various classes for the widgetset interfaces.

Do you know of any widgetset, whose tabbed control has an idea of 
related pages?

Now at your notes in Mantis #19575:

 >>>>>>>>>>>>>>>>>>>>>
 > IMO it's overkill to base the widget on a TCustomNotebook - the internal
 > representation of the page data is of no interest to the widgetset. A 
simpler
 > base control would serve the same purpose, and would allow to implement a
 > Delphi compatible TTabControl.

overkill is not a problem. The LCL can have more functionality then 
Delphi, what is a problem is having a component based on a wrong class 
hierarchy or having less functionality then Delphi.
<<<<<<<<<<<<<<<<<<<<

You address the wrong class hierarchy of TTabControl, I assume?
I fully agree that TTabControl should inherit from LCL TCustomNotebook.


 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Ummm, I'm not sure about this patch. Some issues:

1> TPagedNotebook is a bad choice for a name, TPagedTabControl is better.
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Feel free to rename it as you like.


 >>>>>>>>>>>>>>>>>>>>>>>>
2> You started by modifying TCustomNotebook ... I would much prefer if 
you started by fixing TTabControl instead.
<<<<<<<<<<<<<<<<<<<<<<<

Since TTabControl has no Pages, some methods and properties have to 
become at least virtual in TCustomNotebook.

Unlike in Delphi, where Pages are introduced only in TPageControl, the 
LCL TCustomNotebook *and* the widgetsets currently do not work without 
pages. But as I proved they *can* work without an PageList :-)

 >>>>>>>>>>>>>>>>>>>>>>>>
3> Your entire description of the bug seams to be based on a wrong 
understanding of how TTabControl should work. Why are you putting a 
TPanel inside a TTabControl??? TTabControl can only contain ... tabs. It 
can never contain a Panel nor a Page, nor anything else.
<<<<<<<<<<<<<<<<<<<<<<<<<

You misunderstand the demo application. In contrast, why does a 
TPageControl put TabSheets into the tabbed widget???

The panels in the demo program only demonstrate that a TTabControl *can* 
have associated controls, *not* bound to TCustomPage derivates, and 
*not* bound to the TTabControl as their parent.


 >>>>>>>>>>>>>>>>>>>>
4> Why do you expect Tabs.Tabs.AddObject to work at all? You should not 
use this AFAIK, you should use TTabControl.Tabs.Add()

http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/ComCtrls_TTabControl_Tabs.html 
[^]
<<<<<<<<<<<<<<<<<<<<

Please look at the sample program in that webpage - it does exactly 
this: hold related components (here an dialog) in the Objects[] property 
of the TTabControl.Tabs. This does *not* work with the LCL TTabControl, 
and this was the reason for my bug report.

Delphi TPageControl *also* uses the Tabs.Objects[] to hold the visible 
pages, associated with the tabs.


 >>>>>>>>>>>>>>>>>>>
I took a deeper look at the problem now and I am even more sure that you 
are starting at the wrong side of it.

TCustomNotebook cannot handle a tab control without pages at the moment, 
the very first thing should be implementing that in all widgetsets. I 
see two solutions:

1> Modify TCustomNotebook in all widgetsets so that it can handle a tab 
control without pages, in this case we would have:

-> TCustomNotebook <-- This class has a WS implementation
---> TPageControl
---> TTabControl
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

This essentiall is what I already did. Not in all widgetsets, but it 
should be easy to fix according problems everywhere. When a TCustomPage 
parameter is used only for passing further parameters to the widgetset, 
e.g. Page.Caption for the tab title, a widgetset should never try to 
deal with such an invisible (dummy) page - no window placement...

I used "ANotebook is TPagedNotebook" in the determination, whether the 
TabCtrl has associated *visible* pages. You can suggest any other 
notebook or page property for that purpose :-)


 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2> Change our hierarchy to this:

TCustomTabControl <-- Without a WS implementation
--> TCustomNotebook <-- This class has a WS implementation
-----> TPageControl
--> TTabControl <-- This class will gain a WS implementation
<<<<<<<<<<<<<<<<<<<<<<<<

Since both paged and unpaged controls are based on the same widget, and 
have much functionality in common, I'd suggest instead:

TCustomTabControl   <-- With basic WS implementation
--> TCustomNotebook <-- With extended WS implementation
-----> TPageControl
--> TTabControl

Then the TWSNotebook class can inherit from TWSTabControl.

Or associate TWSNotebook directly with TPageControl, however you like.


 >>>>>>>>>>>>>>>>>>>>>>>>>>>
The Delphi design of having a base class with tabs and a derivated one 
with pages is stupid and very windows-centric ... we won't be able to 
fully replicate that.
<<<<<<<<<<<<<<<<<<<<<<<<<<<

Sorry, that' nonsense :-(

*Every* tabbed widget can live without associated pages, at least it can 
be shrunk to only show the tabs and nothing else. This is what the 
current TTabControl does: show only the tabs of the embedded 
TCustomNotebook. But why use an embedded control for that purpose, when 
the widget already can do all that itself?


 >>>>>>>>>>>>>>>>>>>>
The closest solution is option 2, with the difference that 
TCustomTabControl will not be usable alone, because it won't have a WS 
implementation.
<<<<<<<<<<<<<<<<<<<<

That's the crappy workaround, currently used in TTabControl :-(


 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Option 1 would require making public a lot of tab stuff into 
TPageControl and a lot of page stuff into TTabControl
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Please give at least one concrete example.

Didn't I prove that a separation of paged from unpaged tabbed 
controls/widgets is feasable with little efforts?

I have already moved the affected stuff from TCustomNotebook into 
TPagedNotebook, and you can move that stuff from TPagedNotebook into 
TPageControl, and remove TPagedNotebook entirely, if you like.

DoDi





More information about the Lazarus mailing list