Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-07

TTabControl reverted to it's old implementation

26 messages · 8 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Felipe Monteiro de Carvalho

Hello,

My attempt to fix TTabControl opened a too big can of worms, so I decided to revert TTabControl to it's previous implementation.

It is not exactly the same as before, but almost the same. Before TTabControl was implemented in two classes: TCustomTabControl and TTabControl, now I joined both into only TTabControl. It is a based in TCustomControl like before.

There is also a new class: TNewTabControl, which is not registered and is ment to receive patches to implement the new tab control. This new tab control might then, when finished, be renamed to TTabControl and the old control might be renamed to TOldTabControl for example.

This way people can keep using the older version of TTabControl, but we still retain correct names for almost all classes.

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Hans-Peter Diettrich: Why not name these controls TOldTabControl and TNewTabControl, and set TTabControl to one…
Hans-Peter Diettrich wrote
Why not name these controls TOldTabControl and TNewTabControl, and set TTabControl to one of both? This will allow to switch easily between both implementations, without changing the user code (resource files...).

The main issue is that Delphi's TTabControl behaves somewhat differently from what I expected, so the old TTabControl was already largely (or completely?) compatible with it's Delphi counterpart, despite the wrong class hierarchy. And I somehow doubt that the new TTabControl will be able to achieve such a degree of Delphi compatibility as the old one. If it doesn't, then we might have the names stay more permanent then temporary. TTabControl for the more Delphi-compatible version, TNewTabControl for the one with the correct class hierarchy.

Felipe Monteiro de Carvalho

Reply by email

Graeme Geldenhuys
to Felipe Monteiro de Carvalho: My attempt to fix TTabControl opened a too big can of worms, so I decided to revert…
Felipe Monteiro de Carvalho wrote 5 lines
There is also a new class: TNewTabControl, which is not registered and is ment to receive patches to implement the new tab control. This new tab control might then, when finished, be renamed to TTabControl and the old control might be renamed to TOldTabControl for example.

Wouldn't using a "new tab control" branch be better suited for this? That way you don't pollute the main line history with this "going back and forward" development of some future tab control.

After all, that is what development branches are for? Just my 2? worth.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Graeme Geldenhuys
to Felipe Monteiro de Carvalho: On Tue, Jul 26, 2011 at 5:04 PM, Hans-Peter Diettrich The main issue is that Delphi's…
Felipe Monteiro de Carvalho wrote
TTabControl for the more Delphi-compatible version, TNewTabControl for the one with the correct class hierarchy.

My I suggest....

TTabControl - The Delphi-compatible one
TLazTabControl - The Lazarus specific one

These names seem a bit more logical than "old" vs "new" vs "some future new version"

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Andreas Schneider
to Hans-Peter Diettrich: Why not name these controls TOldTabControl and TNewTabControl, and set TTabControl to one…
Hans-Peter Diettrich wrote
In the meantime I added AutoSize to the T[New]TabControl, and when my Linux version becomes usable, I'll try to fix the gtk2 etc. errors.

Why not simply work in an SVN Branch (or if you use Git simply in your local working copy)? Cases like this are exactly what version control was designed for. Having "stable" and "unstable" code in one tree and hacking on one or the other is merely a workaround ... but for a problem that doesn't exist, since we DO have version control :-) Once everything works with your new implementation (which others can easily test/confirm when it's a branch), it can be merged and replace the "old" implementation.

Best Regards, Andreas

Reply by email

Hans-Peter Diettrich
to Felipe Monteiro de Carvalho: My attempt to fix TTabControl opened a too big can of worms, so I decided to revert…
There is also a new class: TNewTabControl, which is not registered and is ment to receive patches to implement the new tab control. This new tab control might then, when finished, be renamed to TTabControl and the old control might be renamed to TOldTabControl for example.

Why not name these controls TOldTabControl and TNewTabControl, and set TTabControl to one of both? This will allow to switch easily between both implementations, without changing the user code (resource files...).

In the meantime I added AutoSize to the T[New]TabControl, and when my Linux version becomes usable, I'll try to fix the gtk2 etc. errors.

DoDi

Reply by email

Hans-Peter Diettrich
to Felipe Monteiro de Carvalho: On Tue, Jul 26, 2011 at 5:04 PM, Hans-Peter Diettrich The main issue is that Delphi's…
Show quoted text 10 lines
On Tue, Jul 26, 2011 at 5:04 PM, Hans-Peter Diettrich wrote: > Why not name these controls TOldTabControl and TNewTabControl, and set > TTabControl to one of both? This will allow to switch easily between both > implementations, without changing the user code (resource files...). The main issue is that Delphi's TTabControl behaves somewhat differently from what I expected, so the old TTabControl was already largely (or completely?) compatible with it's Delphi counterpart, despite the wrong class hierarchy.

No, the Tabs.Objects[] behaviour is very different. Also the hierarchy of the child controls is different, due to the added page controls.

And I somehow doubt that the new TTabControl will be able to achieve such a degree of Delphi compatibility as the old one.

Please explain where the new control is not Delphi compatible.

DoDi

Reply by email

Hans-Peter Diettrich
to Graeme Geldenhuys: My I suggest.... TTabControl - The Delphi-compatible one TLazTabControl - The…
Show quoted text 9 lines
On 07/26/2011 04:10 PM, Felipe Monteiro de Carvalho wrote: > TTabControl for the more > Delphi-compatible version, TNewTabControl for the one with the correct > class hierarchy. My I suggest.... TTabControl - The Delphi-compatible one

Which one should that be?

TLazTabControl - The Lazarus specific one

Smells like the old TTabControl.

Compatibility is not an argument when the problems reside in the widgetsets, i.e. the implementation of the basic behaviour of a tabbed control. The widgetsets implement a TPageControl, not a TTabControl, and it requires some more work to separate the excess (page related) code.

DoDi

Reply by email

Hans-Peter Diettrich
to Andreas Schneider: Why not simply work in an SVN Branch (or if you use Git simply in your local working…
Show quoted text 8 lines
At Tuesday, 26.07.2011 on 17:04 Hans-Peter Diettrich wrote: > In the meantime I added AutoSize to the T[New]TabControl, and when > my Linux version becomes usable, I'll try to fix the gtk2 etc. > errors. > Why not simply work in an SVN Branch (or if you use Git simply in your local working copy)?

Why should this ever be required?

I developed the new control version independently from the old one, both versions can be used side-by-side.

Who would fix the widgetset issues in a new branch? These can be fixed in the trunk as well.

DoDi

Reply by email

Graeme Geldenhuys
to Hans-Peter Diettrich: Which one should that be? Smells like the old TTabControl. Compatibility is not an…
Hans-Peter Diettrich wrote
widgetsets, i.e. the implementation of the basic behaviour of a tabbed control. The widgetsets implement a TPageControl, not a TTabControl, and it requires some more work to separate the excess (page related) code.

I remember when I started using Lazarus, some 5 or more years ago, then already there was issues with the various tab/page controls. I'm at least glad to see somebody is trying to address the problems now.

As for the TabControl vs PageControl vs NoteBook vs whatever Delphi has... I understand [which might be wrong] is that the controls are described as follows:

TabControl - this just paints the "tabs" part, and presents the developer with a OnTabChange event. There is NO "body", "panel" or "page" with this component. So there is no place to add components per tab.

PageControl - is a component that has the "tabs" part and an associated "page / panel" for each tab.

NoteBook - I have no idea what is the difference between this and the PageControl. They seem the same to me. The only difference I could see is how you add more tabs. One use a string list property the other is a collection of page objects (I think).

Anyway, I don't want to get into the "battle of the tabs" with you and Felipe. I just think, from a developer point of view, you need to take your battle into a separate branch and fight it out there. Once a solution has been agreed upon and the implementation meets the Delphi-compatibility criteria, then merge it back into Trunk. But that's just me thinking out loud.

If all underlying widgetsets (GTK, Qt, Win32, etc) don't have the needed components to build the LCL on, then you guys obviously need to look into writing a custom drawn component which will meet all the needs.

Isn't component development fun. ;-)

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Graeme Geldenhuys
to Hans-Peter Diettrich: Why should this ever be required? I developed the new control version independently from…
Hans-Peter Diettrich wrote
> Why not simply work in an SVN Branch (or if you use Git simply in > your local working copy)? Why should this ever be required?

Oh, lets see... You and Felipe don't agree on a solution! So what happens now? Commit, Revert, commit, no revert, commit, no revert etc... So 1 or 2 years down the line if some poor soul is trying to fix a page/tab control bug the development history of said component is absolutely rubbish!

Fight your battle in a branch, once done, then do a clean merge or single flatted commit into Trunk. This is "working with revision control 101".

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Felipe Monteiro de Carvalho
to Graeme Geldenhuys
Graeme Geldenhuys wrote
Oh, lets see... You and Felipe don't agree on a solution! So what happens now? Commit, Revert, commit, no revert, commit, no revert etc...

That was not a commit war.

I commited many large changes and then I reverted 2 changes back. In all cases I was commiting, and the revert was not motivated by disagreeing, but rather because my knowledge of how the TTabControl should work was incomplete at the time that I made the initial changes.

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Graeme Geldenhuys: I remember when I started using Lazarus, some 5 or more years ago, then already there was…
Graeme Geldenhuys wrote
TabControl - this just paints the "tabs" part, and presents the ? ? ? ? ? ? developer with a OnTabChange event. There is NO "body", ? ? ? ? ? ? "panel" or "page" with this component. So there is no ? ? ? ? ? ? place to add components per tab.

That's what I though initially, but it is wrong. In Delphi this control allows other controls to be placed on it, so it effectively has 1 sheet. Changing the tabs triggers OnTabChange but doesn't change the visible sheet (since there is only 1 anyway)

PageControl - is a component that has the "tabs" part and an associated ? ? ? ? ? ? ?"page / panel" for each tab.

correct.

Show quoted text 5 lines
NoteBook ? ?- I have no idea what is the difference between this and ? ? ? ? ? ? ?the PageControl. They seem the same to me. The only ? ? ? ? ? ? ?difference I could see is how you add more tabs. One use ? ? ? ? ? ? ?a string list property the other is a collection of ? ? ? ? ? ? ?page objects (I think).

That's how it was implemented before I fixed it. The correct TNotebook has no tabs, only sheets without any border. It can be used, for example, to implement a "Assistent"-like screen without using multiple forms. Click on a button and change the visible sheet for the whole form.

I also use it in apps where you click on a button and then part of the view changes to reflect which tool is selected.

I use the new and correct TNotebook quite a lot actually =)

Felipe Monteiro de Carvalho

Reply by email

Graeme Geldenhuys
to Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho wrote
That's what I though initially, but it is wrong. In Delphi this control allows other controls to be placed on it, so it effectively has 1 sheet.

And I believe that to be a bug in Delphi. See attachment: tabcontrol.png

Dropping a Memo onto TTabControl is indeed possible, but look at the outcome! Components can be moved _over_ the tabs. Such behaviour should not be allowed. Yet when you set the Memo1.Align := alClient, then in maximizes the memo to fit underneath the tabs. This is very conflicting behaviour - thus the reason why I think that component is rather dodgy in behaviour.

Then again I have no idea where you guys draw the line on Delphi-compatibility. Do you implement Delphi bugs in LCL too?

Use a tool like MWSnap 3's "window information" feature. This allows you to move the mouse over applications (even better if they are Delphi apps) and it tells you the components used, and outlines the component bounds. I did this on Delphi 7 for you. See attachment of MWSnap Window Information used on Delphi's Object Inspector window. I believe TXTabControl to be a descendant of TTabControl (I remember having a tool to query that as well). Note the bounds of the tab control - they do not cover the grid in the Object Inspector. Many other applications apply the same principle.

Show quoted text 8 lines
> NoteBook - I have no idea what is the difference between this and > the PageControl. They seem the same to me. The only > difference I could see is how you add more tabs. One use > a string list property the other is a collection of > page objects (I think). That's how it was implemented before I fixed it. The correct TNotebook has no tabs, only sheets without any border.

You are correct about TNotebook, but I was thinking of the TTabbedNotebook as can bee seen in Delphi 7. Then again, having a Notebook, TabbedNotebook, PageControl, TabControl etc. is just damn confusing to developers. Borland clearly had no idea what they were trying to achieve with all those variations. Not to mention that TNotebook and TTabbedNotebook are not related at all, if you look and there class hierarchy.

It can be used, for example, to implement a "Assistent"-like screen without using multiple forms. Click on a button and change the visible sheet for the whole form.

I have done similar in my Delphi 7 days with a simple TPanel and many TFrame descendants.

I also use it in apps where you click on a button and then part of the view changes to reflect which tool is selected.

I simplified this whole tab/notebook mess in fpGUI. I have one PageControl component. It's tabs can possitioned at the top, bottom, left or right, or even show no tabs. Future improvents will be to change the tab style to Tabs, Buttons, Flat Buttons etc. You really don't need 5 components as is done in Delphi. Even Borland noticed that, because Delphi 7 CLX or Kylix has limited it to two components only.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ -------------- next part -------------- A non-text attachment was scrubbed... Name: tabcontrol.png Type: image/png Size: 511 bytes Desc: not available URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110727/09195695/attachment-0002.png> -------------- next part -------------- A non-text attachment was scrubbed... Name: delpi_object_inspector.png Type: image/png Size: 4290 bytes Desc: not available URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110727/09195695/attachment-0003.png>

Reply by email

Mattias Gaertner
to Graeme Geldenhuys
Show quoted text 13 lines
On 07/27/2011 09:03 AM, Felipe Monteiro de Carvalho wrote: > That's what I though initially, but it is wrong. In Delphi this > control allows other controls to be placed on it, so it effectively > has 1 sheet. And I believe that to be a bug in Delphi. See attachment: tabcontrol.png Dropping a Memo onto TTabControl is indeed possible, but look at the outcome! Components can be moved _over_ the tabs. Such behaviour should not be allowed. Yet when you set the Memo1.Align := alClient, then in maximizes the memo to fit underneath the tabs. This is very conflicting behaviour - thus the reason why I think that component is rather dodgy in behaviour.

This is the case for many Delphi controls. For instance TGroupBox. This is more a design decision of the VCL. Some programmers need such a feature, so you can not say it is a "bug" in general. But since the beginning of the LCL it was clear that this is a winapi special and can/will not be supported by the LCL.

The converter has some routines to automatically adjust some of these client coordinates.

Then again I have no idea where you guys draw the line on Delphi-compatibility. Do you implement Delphi bugs in LCL too?

It depends on the case.
Some semi good features are implemented.
For example the LCL TPanel allows to move child controls over its frame.

[...]

Mattias

Reply by email

Martin
to Graeme Geldenhuys: And I believe that to be a bug in Delphi. See attachment: tabcontrol.png Dropping a Memo…
Graeme Geldenhuys wrote 8 lines
On 07/27/2011 09:03 AM, Felipe Monteiro de Carvalho wrote: > That's what I though initially, but it is wrong. In Delphi this > control allows other controls to be placed on it, so it effectively > has 1 sheet. And I believe that to be a bug in Delphi. See attachment: tabcontrol.png Dropping a Memo onto TTabControl is indeed possible, but look at the outcome! Components can be moved _over_ the tabs.

If I had to guess, I would say that Delphi has the client-area (never mind the overlap), because Delphi does not have the same anchors as Lazarus. So it is more often required to nest components, to archive a layout. Just a guess...

Anyway, as for an implementation in Lazarus, I would think it would be good to replicate. even if only for compatibility, so people can convert there Delphi projects.

Lazarus can add the autosize, which would make it a tab only control, and the client area could be left empty.It would be the developers choice.

As for the overlap, and the Child.Top = 0 location.

In Delphi Child.Top = zero means overlap the tabs (as does it for TGroupBox).
IMHO I see no unsolvable issue, if that was different in Lazarus. The Delphi-Convertor could probably adjust the Top coordinates of a TTabControl's direct children.

Show quoted text 11 lines
>> NoteBook - I have no idea what is the difference between this and >> the PageControl. They seem the same to me. The only >> difference I could see is how you add more tabs. One use >> a string list property the other is a collection of >> page objects (I think). > That's how it was implemented before I fixed it. The correct TNotebook > has no tabs, only sheets without any border. You are correct about TNotebook, but I was thinking of the TTabbedNotebook as can bee seen in Delphi 7. Then again, having a Notebook, TabbedNotebook, PageControl, TabControl etc. is just damn confusing to developers.

Notebooks are CustomControls (haven't checked TTabedNotebook...) Tab/PageControl are Wincontrol

There are other occasions of very similar components, that mainly differ in this inheritance point I also use it in apps where you click on a button and then part of the

> view changes to reflect which tool is selected. I simplified this whole tab/notebook mess in fpGUI. I have one PageControl component.

Do you have a difference between WinControls and none WinControls? Or actually do you have a need for it?

probably not... Though I don't know how InvalidateRect is implement for fpGui? You must have some interaction with the OS/Widgetset there, as invalidation can happen from outside the app

Anyway, in W32 (and probably others too) If I invalidate multiply rects of the same WinControl (a wincontrol has a handle in the OS) then the minimum bounding rect is invalidated => so I may end up painting more than actually required.
If I have separate WinControls, then each of them has it's invalidated rect (and each will get a callback invoking it's Paint.

So it's a question if you have a very time-expensive paint handler, you may want to have more handles, and paint less

Reply by email

Hans-Peter Diettrich
to Graeme Geldenhuys: I remember when I started using Lazarus, some 5 or more years ago, then already there was…
Show quoted text 17 lines
As for the TabControl vs PageControl vs NoteBook vs whatever Delphi has... I understand [which might be wrong] is that the controls are described as follows: TabControl - this just paints the "tabs" part, and presents the developer with a OnTabChange event. There is NO "body", "panel" or "page" with this component. So there is no place to add components per tab. PageControl - is a component that has the "tabs" part and an associated "page / panel" for each tab. NoteBook - I have no idea what is the difference between this and the PageControl. They seem the same to me. The only difference I could see is how you add more tabs. One use a string list property the other is a collection of page objects (I think).

A PageControl logically consists of a TabControl and a NoteBook, this IMO is the idea behind these 3 controls.

Then it also makes sense to have tabs only for selected pages, with possibly more pages "between" two tabs; these pages have to be addressed differently, e.g. by next/prev buttons on the pages themselves.

DoDi

Reply by email

Hans-Peter Diettrich
to Graeme Geldenhuys: And I believe that to be a bug in Delphi. See attachment: tabcontrol.png Dropping a Memo…
Show quoted text 9 lines
On 07/27/2011 09:03 AM, Felipe Monteiro de Carvalho wrote: > That's what I though initially, but it is wrong. In Delphi this > control allows other controls to be placed on it, so it effectively > has 1 sheet. And I believe that to be a bug in Delphi. See attachment: tabcontrol.png Dropping a Memo onto TTabControl is indeed possible, but look at the outcome! Components can be moved _over_ the tabs.

Isn't this *exactly* what you *can* do with a real-life notebook?

Such behaviour should not be allowed.

Overlapping components can occur everywhere, and may have their place in some (CAD...) applications. I see no need to restrict an GUI designer in any way, but of course there should exist means to prevent unwanted overlapping, when components are resized at runtime (tabs added, labels enlarged for a translated heading...). All that is not restricted to tabbed controls.

Yet when you set the Memo1.Align := alClient, then in maximizes the memo to fit underneath the tabs. This is very conflicting behaviour -

IMO this is just one solution for above problems, where do you see any conflict?

If you are not happy with this solution, then separate the tabs from the "body", and put all related components into an dedicated (notebook) container, and make sure that it never will overlap the tabs. But what when a multi-line tabctrl will expand itself when tabs are added? Then *you* (designer) are responsible again for handling overlaps.

Use a tool like MWSnap 3's "window information" feature. This allows you to move the mouse over applications (even better if they are Delphi apps) and it tells you the components used, and outlines the component bounds.

This is what the Delphi Winspector already did years ago [dunno remember the exact name of that tool]. Such tools rely on all controls being handled by a known widgetset, what is not true for e.g. Java (or newer Qt?) applications, with their own component management. The same on non-Windows platforms, where only windows are managed by a known window manager, while all controls are implemented by some widgetset (qt, gtk...), which is not known to the outer world.

Show quoted text 5 lines
> I also use it in apps where you click on a button and then part of the > view changes to reflect which tool is selected. I simplified this whole tab/notebook mess in fpGUI. I have one PageControl component.

This is what we have in Lazarus, too. What's so bad with having *more* components - except that somebody has to supply and support every component?

You really don't need 5 components as is done in Delphi. Even Borland noticed that, because Delphi 7 CLX or Kylix has limited it to two components only.

You obviously missed the compatibility issue :-(

Delphi 1 has implemented treeviews, tabs and notebooks, which have not been available on the Win3.x platform. When Microsoft later implemented a tabbed control, they didn't follow the Delphi model, so that now Delphi offers new Win32 (COM) compatible components, as well as legacy (Win3.1) components.

These different models obviously also confused the Lazarus developers, leading to inconsistent or incompatible implementations of all these components. Nowadays we may agree to drop support for the Delphi 1 components from the LCL, but we could as well retain the legacy components in their own (Win3.1) package, possibly with limited support on newer widgetsets.

But while the developer of an widgetset is free in the choice and implementation of its own (fpGui...) components, the LCL should support the native widgets, provided by a platform or widgetset. This is where problems with the different widget models arise, when e.g. gtk2 provides a tabbed control that is quite different from its Win32 counterpart. And it doesn't help to point out how something *should* be implemented, when an existing widgetset implements a different model for a complex control.

DoDi

Reply by email

Hans-Peter Diettrich
to Martin: If I had to guess, I would say that Delphi has the client-area (never mind the overlap),…
In Delphi Child.Top = zero means overlap the tabs (as does it for TGroupBox).

That's the behaviour of the underlying COM control, and since Delphi (VCL) only supports Win32 widgets, this has been okay in the past.

IMHO I see no unsolvable issue, if that was different in Lazarus. The Delphi-Convertor could probably adjust the Top coordinates of a TTabControl's direct children.

Lazarus better should have based the LCL on CLX, instead of the VCL. IMO a Delphi GUI designer should use (have used) the CLX for all applications that shall be usable on multiple platforms. It really doesn't make much sense to support Win32 quirks in Lazarus, or to supply an VCL to CLX (gtk, cocoa...) converter, that finally cannot handle really all widgetset specific cases.

Delphi designers already had to accept a different component library for Kylix, and an never finished library for .NET. They'll have to face another different component library in cross-platform Delphi - if such a version will ever exist. Lazarus *can not* offer an perfect VCL clone, with identical behaviour on all platforms. It's not a good marketing argument, that a converter will allow to use every existing Delphi application on other platforms, when such a converter only can handle a few problems. Instead it should be made clear to the Delphi-to-Lazarus migrants, that they may have to modify their GUI themselves, before an application will look good and behave properly on other platforms or with different widgetsets.

IMO it would make sense when a future Lazarus would support two libraries: a Delphi compatible one, with full support on Windows and limited support on other platforms, and a cross-platform library with (almost) full support on all platforms. This would reduce the development efforts to a fraction of the current requirements, achievable with the limited number of core developers.

DoDi

Reply by email

Graeme Geldenhuys
to Martin: If I had to guess, I would say that Delphi has the client-area (never mind the overlap),…
Martin wrote
Notebooks are CustomControls (haven't checked TTabedNotebook...) Tab/PageControl are Wincontrol

Ah. I saw that TNotebook is custom drawn (not that there is much to draw), but can't recall TTabbedNotebook. But I think you are right, that both of them are probably custom drawn controls.

Show quoted text 5 lines
> I simplified this whole tab/notebook mess in fpGUI. I have one > PageControl component. Do you have a difference between WinControls and none WinControls? Or actually do you have a need for it?

All widgets in fpGUI have window handles. Some widgets are built up of multiple widgets (window handles) too.

Anyway, in W32 (and probably others too) If I invalidate multiply rects of the same WinControl (a wincontrol has a handle in the OS) then the minimum bounding rect is invalidated => so I may end up painting more than actually required.

All painting in fpGUI is done via double buffering, so painting is normally quite fast. But yes, some components are tweaked as composite widgets (various areas have there own window handles) thus reducing painting too.

So it's a question if you have a very time-expensive paint handler, you may want to have more handles, and paint less

This is not always the case. Take Qt as an example. The used to be a window-handle-per-widget framework, but after Qt 4.5 switched to a single window-handle-per-window. They felt the latter gave them better performance - I experienced the opposite in fpGUI.

Regards, ? - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net

Reply by email

Martin
to Graeme Geldenhuys
Graeme Geldenhuys wrote
> So it's a question if you have a very time-expensive paint handler, you may > want to have more handles, and paint less This is not always the case.

Well that's why I wrote: "time-expensive paint handler" Having many handles, and calling many paint handlers costs time as well.

Show quoted text 5 lines
Take Qt as an example. The used to be a window-handle-per-widget framework, but after Qt 4.5 switched to a single window-handle-per-window. They felt the latter gave them better performance - I experienced the opposite in fpGUI.

Reply by email

Graeme Geldenhuys
to Hans-Peter Diettrich: Isn't this *exactly* what you *can* do with a real-life notebook? Overlapping components…
Hans-Peter Diettrich wrote 6 lines
> Yet when you set the Memo1.Align := alClient, then in > maximizes the memo to fit underneath the tabs. This is very conflicting > behaviour - IMO this is just one solution for above problems, where do you see any conflict?

What is the real (0,0) position? The one Align=alClient displays, or the real top-left of the TTabControl.

But what when a multi-line tabctrl will expand itself when tabs are added?

The solution is easy. Find the developer that suggested and implemented multi-line tabs and SHOOT them! :) I refused to implement that in fpGUI because it confuses the hell out of everybody and definitely doesn't make the UI easier to use. If you require that many tabs, rethink your UI design. Hense the reason everybody seems to now resort to a Treeview on the left, client area on the right. Or a listbox type component on the left and client area on the right.

Imagine Lazarus used a multi-line tab control of the "Environment -> Options" window. That would be somewhere around 30 tabs probably taking up the whole screen just for the tabs alone.

exact name of that tool]. Such tools rely on all controls being handled by a known widgetset, what is not true for e.g. Java (or newer Qt?)

It requires each control to have a window handle. I implemented a similar tool for X11. But yes, the latest Qt and GTK2 now use a single window handle per window, so such tools don't work on them any more.

My tool still works on GTK2 apps in Ubuntu 8.04 though, so GTK2 changed somewhere after that I think.

Delphi 1 has implemented treeviews, tabs and notebooks, which have not been available on the Win3.x platform. When Microsoft later implemented a tabbed control, they didn't follow the Delphi model, so that now Delphi offers new Win32 (COM) compatible components, as well as legacy (Win3.1) components.

I only started using Delphi from version 4 onwards. But thanks for the history. Now I finally know the reason for the Win3.1 tab. :-)

control that is quite different from its Win32 counterpart. And it doesn't help to point out how something *should* be implemented, when an existing widgetset implements a different model for a complex control.

That's the challenge you guys choose for LCL, so you better live with it. :-/ I'm afraid those incompatibilities will continue forever.

Regards, ? - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net

Reply by email

Graeme Geldenhuys
to Martin: Well that's why I wrote: "time-expensive paint handler" Having many handles, and calling…
Martin wrote
Having many handles, and calling many paint handlers costs time as well.

Probably, but painting is overall reduced because not the whole window [read this as a Form] needs to be repainted, just the affected windows/widgets which are pretty much guaranteed to be smaller than the Form they appear in.

Regards, ? - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net

Reply by email

Zaher Dirkey
to Graeme Geldenhuys: I remember when I started using Lazarus, some 5 or more years ago, then already there was…
Graeme Geldenhuys wrote
Isn't component development fun. ;-)

Yes, fun, for that i have my own special PageControl on Delphi and Lazarus. http://www.minilib.org/doc/lazarus/components/native#ntvpagecontrol

Regards
Zaher Dirkey
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110727/3339b605/attachment.html>

Reply by email

Martin Schreiber
to Martin: If I had to guess, I would say that Delphi has the client-area (never mind the overlap),…
Martin wrote 18 lines
>> view changes to reflect which tool is selected. > > I simplified this whole tab/notebook mess in fpGUI. I have one > PageControl component. Do you have a difference between WinControls and none WinControls? Or actually do you have a need for it? probably not... Though I don't know how InvalidateRect is implement for fpGui? You must have some interaction with the OS/Widgetset there, as invalidation can happen from outside the app Anyway, in W32 (and probably others too) If I invalidate multiply rects of the same WinControl (a wincontrol has a handle in the OS) then the minimum bounding rect is invalidated => so I may end up painting more than actually required. If I have separate WinControls, then each of them has it's invalidated rect (and each will get a callback invoking it's Paint.

In MSEgui twidget has no window handle. Attached to the top level twidget is a twindow which manages the window handle and communicates with the window manager. Every twidget can act as top level widget so there is no distinction between WinControls and none WinControls in MSEgui. twindow collects invalidataed rects in a region. While updating the window only twidget which intersect the update region were painted. The widgets paint on a common offscreen bitmap for platform independent double buffering.

Martin

Reply by email

Hans-Peter Diettrich
to Graeme Geldenhuys: What is the real (0,0) position? The one Align=alClient displays, or the real top-left of…
Show quoted text 9 lines
On 27 July 2011 17:00, Hans-Peter Diettrich wrote: >> Yet when you set the Memo1.Align := alClient, then in >> maximizes the memo to fit underneath the tabs. This is very conflicting >> behaviour - > IMO this is just one solution for above problems, where do you see any > conflict? What is the real (0,0) position? The one Align=alClient displays, or the real top-left of the TTabControl.

Ask the Windows developers, why their tab control has tabs inside its client area.

Delphi implements an DisplayRect property, that uses the TCM_ADJUSTRECT message for the conversion between the window and client area.

DoDi

Reply by email