Sign in Join

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

Mailing lists / lazarus / 2010-04

Autosize behaviour

65 messages · 11 people · –

Reply by email Subscribe to this list Your subscription

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

Michael Van Canneyt

Hi,

In delphi, setting a panel's AutoSize property to 'true' and aligning it to a form edge, makes the panel disappear when the project is run. This is logical, because, if there are no controls on the panel, the needed size is zero.

In Lazarus, the panel is still shown.

Is this a known bug ?

Michael.

Reply by email

Michael Van Canneyt
to Michael Van Canneyt
Michael Van Canneyt wrote 10 lines
Hi, In delphi, setting a panel's AutoSize property to 'true' and aligning it to a form edge, makes the panel disappear when the project is run. This is logical, because, if there are no controls on the panel, the needed size is zero. In Lazarus, the panel is still shown. Is this a known bug ?

Follow-up:
The problem appears both with -dOldAutoSize and without -dOldAutoSize.

Michael.

Reply by email

Mattias Gaertner
to Michael Van Canneyt: In delphi, setting a panel's AutoSize property to 'true' and aligning it to a form edge,…
Show quoted text 6 lines
Hi, In delphi, setting a panel's AutoSize property to 'true' and aligning it to a form edge, makes the panel disappear when the project is run. This is logical, because, if there are no controls on the panel, the needed size is zero.

Yes, and this is the problem. A visible control must not have the size 0,0. It makes no sense. This is bad in the designer. The gtk does not like it.
Therefore the LCL ignores the child bounds if no childs are there.

In Lazarus, the panel is still shown. Is this a known bug ?

A feature. You are the first asking. Do you need it?

Mattias

Reply by email

Michael Van Canneyt
to Mattias Gaertner
Mattias Gaertner wrote 21 lines
On Sun, 4 Apr 2010 19:21:00 +0200 (CEST) Michael Van Canneyt wrote: > Hi, > > In delphi, setting a panel's AutoSize property to 'true' and aligning it to a > form edge, makes the panel disappear when the project is run. > This is logical, because, if there are no controls on the panel, > the needed size is zero. Yes, and this is the problem. A visible control must not have the size 0,0. It makes no sense. This is bad in the designer. The gtk does not like it. Therefore the LCL ignores the child bounds if no childs are there. > In Lazarus, the panel is still shown. > > Is this a known bug ? A feature. You are the first asking. Do you need it?

What is "need"... The current behaviour is definitely not compatible to delphi.

In Delphi, you can make dock zones along the edges of your form by dropping 4 panels and aligning them along the edges of the form. If autosize=true, then they have size 0 when the app is run (not when designed), but you can dock controls on them, since there is a "fuzzy" zone of 10 pixels. No code is needed, and you can then dock toolbars etc. along the edges of the form.

If lazarus is not compatible:
It means that I must put width/height=0 manually in the IDE (or do this when the form is created), and enable autosizing as soon as the first control is docked on the panel, and when a docked control is removed from the panel, I must put width/height again to zero, manually.

IMHO Autosize should do what it says at runtime, not with exceptions: fit the children. If there are none: size=0. For aligned, this means just the dimension which is orthogonal to the aligned dimension: alRight -> width=0.

I agree it is all rather sloppy, but then I think Layouting as a whole is sloppy :-)

Unless someone has a better idea for dock zones around the edge of a form without having to write code...

Michael.

Reply by email

Hans-Peter Diettrich
to Mattias Gaertner: On Sun, 4 Apr 2010 19:21:00 +0200 (CEST) Yes, and this is the problem. A visible control…
Show quoted text 9 lines
> In delphi, setting a panel's AutoSize property to 'true' and aligning it to a > form edge, makes the panel disappear when the project is run. > This is logical, because, if there are no controls on the panel, > the needed size is zero. Yes, and this is the problem. A visible control must not have the size 0,0. It makes no sense. This is bad in the designer. The gtk does not like it. Therefore the LCL ignores the child bounds if no childs are there.

Please keep initially invisible DockSites working, which expand when a control is docked into them. See the ElasticSite demo.

DoDi

Reply by email

Hans-Peter Diettrich
to Michael Van Canneyt: What is "need"... The current behaviour is definitely not compatible to delphi. In…
Show quoted text 5 lines
In Delphi, you can make dock zones along the edges of your form by dropping 4 panels and aligning them along the edges of the form. If autosize=true, then they have size 0 when the app is run (not when designed), but you can dock controls on them, since there is a "fuzzy" zone of 10 pixels.

Such DockSites should work without AutoSize, because their extent is determined by the DockManager - which is not involved in autosizing. The free extent of an elastic docksite should be user-adjustable, by means of an splitter. They worked until now, at least with the Win32 and gtk2 widgetsets.

The influence rectangle of a docksite is the control's rectangle, extended by 10 pixels in every direction. It it used only in the determination of the target site, not in the layout.

No code is needed, and you can then dock toolbars etc. along the edges of the form.

Code is needed to extend and shrink the sites - also in Delphi. The docked size of the controls is not normally useful to determine the extent of a docksite, instead the DockManager controls the layout of the site, by adjusting all docked controls to the given extent of the site.

Unless someone has a better idea for dock zones around the edge of a form without having to write code...

I already asked for an (user selectable) layout manager some time ago. Such a manager would replace or include docking managers, that essentially control the *layout* of a docksite, while docking itself is only a minor addition. Then AutoSize should be handled by the applicable layout manager, and anchor docking will become just another layout manager. A stable algorithm and protocol (API) has to be established, that allows all layout managers to work together.

DoDi

Reply by email

Michael Van Canneyt
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 16 lines
Michael Van Canneyt schrieb: > In Delphi, you can make dock zones along the edges of your > form by dropping 4 panels and aligning them along the edges of the form. If > autosize=true, then they have size 0 when the app is run (not when > designed), but you can dock controls on them, since there is a "fuzzy" zone > of 10 pixels. Such DockSites should work without AutoSize, because their extent is determined by the DockManager - which is not involved in autosizing. The free extent of an elastic docksite should be user-adjustable, by means of an splitter. They worked until now, at least with the Win32 and gtk2 widgetsets. The influence rectangle of a docksite is the control's rectangle, extended by 10 pixels in every direction. It it used only in the determination of the target site, not in the layout.

I know. That is why setting

Show quoted text 5 lines
> No code is needed, and you can then dock toolbars etc. along the edges of > the form. Code is needed to extend and shrink the sites - also in Delphi.

have a counter-example on my disk here.

I didn't test docking 2 controls on it, but when docking only 1 control, you don't need any code whatsoever in Delphi.

The docked size of the controls is not normally useful to determine the extent of a docksite, instead the DockManager controls the layout of the site, by adjusting all docked controls to the given extent of the site.

And this is not so in delphi when the panel has autosize=true.

Show quoted text 10 lines
> Unless someone has a better idea for dock zones around the edge of a form > without having to write code... I already asked for an (user selectable) layout manager some time ago. Such a manager would replace or include docking managers, that essentially control the *layout* of a docksite, while docking itself is only a minor addition. Then AutoSize should be handled by the applicable layout manager, and anchor docking will become just another layout manager. A stable algorithm and protocol (API) has to be established, that allows all layout managers to work together.

I have been thinking about layout managers. I think that this should be an add-on to the currently existing layouting (to preserve delphi compatibility): I imagine a component that one drops on a form.
One sets the 'target' control (control whose children should be managed) and some properties.

Depending on the layout one wants, a different component must be dropped:

TLayout
+- TAbsoluteLayout
+- THBoxLayout
+- TVBoxLayout
+- TTableLayout
+- TBorderLayout
...
Each descendent has different properties. Changing the layout just means dropping another component; something that can be done run-time.

Something like this exists in ExtJS, and it works very well.

The only thing I am unsure about is whether TControl should be made TLayout-aware. As far as I understand, a layouter only needs to be able to handle rectangles, within some restrictions (some callbacks to get min/max rectangles). It need not know anything about TControl or it's properties, and as such could be implemented totally independent of the LCL.

I discussed this idea once with Mattias Gaertner, but he seems to disagree on the TControl-unawareness, if I recall correctly.

Maybe the planned Lazarus day in the netherlands would be a good place to discuss this and settle things once and for all :-)

Michael.

Reply by email

Martin
to Michael Van Canneyt
Michael Van Canneyt wrote 27 lines
> I already asked for an (user selectable) layout manager some time > ago. Such a manager would replace or include docking managers, that > essentially control the *layout* of a docksite, while docking itself > is only a minor addition. Then AutoSize should be handled by the > applicable layout manager, and anchor docking will become just > another layout manager. A stable algorithm and protocol (API) has to > be established, that allows all layout managers to work together. I have been thinking about layout managers. I think that this should be an add-on to the currently existing layouting (to preserve delphi compatibility): I imagine a component that one drops on a form. One sets the 'target' control (control whose children should be managed) and some properties. Depending on the layout one wants, a different component must be dropped: TLayout +- TAbsoluteLayout +- THBoxLayout +- TVBoxLayout +- TTableLayout +- TBorderLayout ... Each descendent has different properties. Changing the layout just means dropping another component; something that can be done run-time.

+1

The only thing I am unsure about is whether TControl should be made TLayout-aware.

IHMO probably not, except for providing the cneeded callbacks/hooks

Martin

Reply by email

Michael Van Canneyt
to Michael Van Canneyt: I know. That is why setting have a counter-example on my disk here. I didn't test docking…
Show quoted text 10 lines
> by 10 pixels in every direction. It it used only in the determination of > the target site, not in the layout. I know. That is why setting > >> No code is needed, and you can then dock toolbars etc. along the edges of >> the form. > > Code is needed to extend and shrink the sites - also in Delphi.

A small follow-up on this:

1. What code is needed or can be used in Lazarus ? In the OnDockDrop event, The width/height of the control which will be docked are no longer available. (they are 0, with the latest lazarus, no -dOldAutoSize, and the panel to dock on has height/width 0 depending on alignment)

2. The EasyDocManager MakeSite and SiteTest projects fail to load (TDockSite base class not available), and easyeditor crashes when run and 'open file' is used. Maybe this can be fixed.

Michael.

Reply by email

Hans-Peter Diettrich
to Michael Van Canneyt: I know. That is why setting have a counter-example on my disk here. I didn't test docking…
Show quoted text 5 lines
I have been thinking about layout managers. I think that this should be an add-on to the currently existing layouting (to preserve delphi compatibility): I imagine a component that one drops on a form. One sets the 'target' control (control whose children should be managed) and some properties.

I imagine a Layout property for TWinControls, or an intermediate layer, that is initialized to the Delphi compatible manager. That property then can be assigned any other layout manager.

Show quoted text 7 lines
The only thing I am unsure about is whether TControl should be made TLayout-aware. As far as I understand, a layouter only needs to be able to handle rectangles, within some restrictions (some callbacks to get min/max rectangles). It need not know anything about TControl or it's properties, and as such could be implemented totally independent of the LCL.

The layout should take into account the standard TControl properties, including alignment, constraints and anchors. It also should use the layout managers of child controls, for forward/backward transfer of autosize information.

DoDi

Reply by email

Michael Van Canneyt
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 11 lines
Michael Van Canneyt schrieb: > I have been thinking about layout managers. I think that this should be an > add-on > to the currently existing layouting (to preserve delphi compatibility): I > imagine a component that one drops on a form. One sets the 'target' control > (control whose children should be managed) and some properties. I imagine a Layout property for TWinControls, or an intermediate layer, that is initialized to the Delphi compatible manager. That property then can be assigned any other layout manager.

That is the same as what I am saying, only the arrow points in the opposite direction. I want to avoid this extra TWinControl property.

Show quoted text 12 lines
> The only thing I am unsure about is whether TControl should be made > TLayout-aware. > As far as I understand, a layouter only needs to be able to handle > rectangles, > within some restrictions (some callbacks to get min/max rectangles). It > need not know anything about TControl or it's properties, and as such could > be implemented totally independent of the LCL. The layout should take into account the standard TControl properties, including alignment, constraints and anchors. It also should use the layout managers of child controls, for forward/backward transfer of autosize information.

This is *exactly* what I want to avoid.

- Either one uses the 'ordinary' delphi properties, and only those.

- Or one uses layouters.

But not a mixture of both, which will be a source of implementation/usage problems and confusion. Keep it simple.

Once this split works correctly, you can always later try to create a TLayout descendent which tries to mimic Delphi behaviour, taking into account all TControl/TWincontrol properties; Then remove all old code and insert the new layouter.

In my opinion, this approach guarantees has a bigger chance of success than immediatly trying to do everything at once...

Michael.

Reply by email

Mattias Gaertner
to Michael Van Canneyt: What is "need"... The current behaviour is definitely not compatible to delphi. In…
Show quoted text 33 lines
On Mon, 5 Apr 2010, Mattias Gaertner wrote: > On Sun, 4 Apr 2010 19:21:00 +0200 (CEST) > Michael Van Canneyt wrote: > >> Hi, >> >> In delphi, setting a panel's AutoSize property to 'true' and aligning it to a >> form edge, makes the panel disappear when the project is run. >> This is logical, because, if there are no controls on the panel, >> the needed size is zero. > > Yes, and this is the problem. A visible control must not have the size > 0,0. It makes no sense. This is bad in the designer. The gtk does not > like it. > Therefore the LCL ignores the child bounds if no childs are there. > > >> In Lazarus, the panel is still shown. >> >> Is this a known bug ? > > A feature. You are the first asking. Do you need it? What is "need"... The current behaviour is definitely not compatible to delphi. In Delphi, you can make dock zones along the edges of your form by dropping 4 panels and aligning them along the edges of the form. If autosize=true, then they have size 0 when the app is run (not when designed), but you can dock controls on them, since there is a "fuzzy" zone of 10 pixels. No code is needed, and you can then dock toolbars etc. along the edges of the form.

I see.

I changed a few things:

TPanel paints its borders itself and sets AdjustClientRect. This was ignored when no childs were there. I fixed that bug. Now empty panels are autosized to 2,2 (the 1 pixel border).
Panels without borders will autosize to 0,0, unless the interface limits this to 1,1 - like the gtk.

Show quoted text 9 lines
If lazarus is not compatible: It means that I must put width/height=0 manually in the IDE (or do this when the form is created), and enable autosizing as soon as the first control is docked on the panel, and when a docked control is removed from the panel, I must put width/height again to zero, manually. IMHO Autosize should do what it says at runtime, not with exceptions: fit the children. If there are none: size=0. For aligned, this means just the dimension which is orthogonal to the aligned dimension: alRight -> width=0.

AutoSize means: use a nice size - the preferred size. For example a TLabel has no childs.

I agree it is all rather sloppy, but then I think Layouting as a whole is sloppy :-) Unless someone has a better idea for dock zones around the edge of a form without having to write code...

Mattias

Reply by email

Michael Van Canneyt
to Mattias Gaertner
Mattias Gaertner wrote 46 lines
On Mon, 5 Apr 2010 10:48:00 +0200 (CEST) Michael Van Canneyt wrote: > > > On Mon, 5 Apr 2010, Mattias Gaertner wrote: > >> On Sun, 4 Apr 2010 19:21:00 +0200 (CEST) >> Michael Van Canneyt wrote: >> >>> Hi, >>> >>> In delphi, setting a panel's AutoSize property to 'true' and aligning it to a >>> form edge, makes the panel disappear when the project is run. >>> This is logical, because, if there are no controls on the panel, >>> the needed size is zero. >> >> Yes, and this is the problem. A visible control must not have the size >> 0,0. It makes no sense. This is bad in the designer. The gtk does not >> like it. >> Therefore the LCL ignores the child bounds if no childs are there. >> >> >>> In Lazarus, the panel is still shown. >>> >>> Is this a known bug ? >> >> A feature. You are the first asking. Do you need it? > > What is "need"... The current behaviour is definitely not compatible to delphi. > > In Delphi, you can make dock zones along the edges of your > form by dropping 4 panels and aligning them along the edges of the form. > If autosize=true, then they have size 0 when the app is run (not when designed), > but you can dock controls on them, since there is a "fuzzy" zone of 10 pixels. > No code is needed, and you can then dock toolbars etc. along the edges of the form. I see. I changed a few things: TPanel paints its borders itself and sets AdjustClientRect. This was ignored when no childs were there. I fixed that bug. Now empty panels are autosized to 2,2 (the 1 pixel border). Panels without borders will autosize to 0,0, unless the interface limits this to 1,1 - like the gtk.
I tried to test, but rev. 24444 of the IDe does not compile;
SourceEditor.pp does not compile.

After fixing that, I tested and would suggest a change (Delphi compatible): in the IDE (when csDesigning is in ComponentState) the original designed size should be kept.

I tried fiddling in lcl/include/wincontrol.inc around line 3379 :

     if WidthIsFixed or (PreferredWidth<0)
     or ((PreferredWidth=0) and (not (csAutoSize0x0 in ControlStyle)) and  (csDesigning in Componentstate)) then
       PreferredWidth:=Constraints.MinMaxWidth(Width);
     if HeightIsFixed or (PreferredHeight<0)
     or ((PreferredHeight=0) and (not (csAutoSize0x0 in ControlStyle)) and (csDesigning in Componentstate)) then
       PreferredHeight:=Constraints.MinMaxHeight(Height);

but can't get it to work :/

Show quoted text 13 lines
> If lazarus is not compatible: > It means that I must put width/height=0 manually in the IDE (or do this when > the form is created), and enable autosizing as soon as the first control is > docked on the panel, and when a docked control is removed from the panel, I must > put width/height again to zero, manually. > > IMHO Autosize should do what it says at runtime, not with exceptions: fit the > children. If there are none: size=0. For aligned, this means just the > dimension which is orthogonal to the aligned dimension: alRight -> width=0. AutoSize means: use a nice size - the preferred size. For example a TLabel has no childs.

Good point. From the Delphi help for TControl.

"Specifies whether the control sizes itself automatically to accommodate its contents."

For TCustomLabel.AutoSize is adapted to say something about the text.

Michael.

Reply by email

Mattias Gaertner
to Michael Van Canneyt: I know. That is why setting have a counter-example on my disk here. I didn't test docking…
Show quoted text 24 lines
[...] I have been thinking about layout managers. I think that this should be an add-on to the currently existing layouting (to preserve delphi compatibility): I imagine a component that one drops on a form. One sets the 'target' control (control whose children should be managed) and some properties. Depending on the layout one wants, a different component must be dropped: TLayout +- TAbsoluteLayout +- THBoxLayout +- TVBoxLayout +- TTableLayout +- TBorderLayout ... Each descendent has different properties. Changing the layout just means dropping another component; something that can be done run-time. Something like this exists in ExtJS, and it works very well. The only thing I am unsure about is whether TControl should be made TLayout-aware. As far as I understand, a layouter only needs to be able to handle rectangles, within some restrictions (some callbacks to get min/max rectangles). It need not know anything about TControl or it's properties, and as such could be implemented totally independent of the LCL.

See below.

I discussed this idea once with Mattias Gaertner, but he seems to disagree on the TControl-unawareness, if I recall correctly.

With the new autosizing it is now possible to think about layout managers.
A layout manager that handles the layout of children of a TWinControl must implement the following:
- a computation of the total preferred space (children plus space). At the moment this is done by TControl.CalculatePreferredSize.
- a computation of the layout (position and size of each child) (AlignControls).
- a computation of the size (DoAutoSize)

The layouter needs access to Left, Top, Width, Height, ClientWidth, ClientHeight, ReadBounds, BaseBounds, BaseParentClientSize, AdjustSize, InvalidatePreferredSize.

Optionally a layouter could layout only a subset of the children (e.g. those with Align=alCustom or only those with default Anchors).

So the LCL must call instead of its own functions the layouter. Namely: DoAutoSize, AlignControl, CalculatePreferredSize, ControlsAligned, CreateControlAlignList, CustomAlignInsertBefore, CustomAlignPosition, DoAlignChildControls.

One solution would be a TWinControl property Layouter.

Maybe the planned Lazarus day in the netherlands would be a good place to discuss this and settle things once and for all :-)

:)

Mattias

Reply by email

Michael Van Canneyt
to Martin
Martin wrote 6 lines
On 05/04/2010 20:26, Michael Van Canneyt wrote: > > I tried to test, but rev. 24444 of the IDe does not compile; > SourceEditor.pp does not compile. My fault, Fixed in 24445

Thanks :)

Michael.

Reply by email

Michael Van Canneyt
to Erwin van den Bosch
Erwin van den Bosch wrote 11 lines
On 5-4-2010 18:26, Michael Van Canneyt wrote: > > Maybe the planned Lazarus day in the netherlands would be a good place to > discuss this and settle things once and for all :-) > > Michael. Has someone a bit more info on this planned lazarus day? url? Date? Location? I think this is very interesting!

See:

http://www.blaisepascal.eu/

26 june 2010 in the neighbourhood of Utrecht.

Michael.

Reply by email

Birger Jansen
to Mattias Gaertner: On Mon, 5 Apr 2010 18:26:36 +0200 (CEST) See below. With the new autosizing it is now…

Sorry for dropping into the discussion...

There is a very good LAyoutControl in the DevExpress suite (Delphi controls). We use it for a lot of projects. I think it is an excellent example of how a layout manager could work in the ideal world:

http://www.devexpress.com/Products/VCL/ExLayoutControl/

If you want to see some specific examples let me know.

Kind regards,
Birger

Mattias Gaertner wrote 70 lines
On Mon, 5 Apr 2010 18:26:36 +0200 (CEST) Michael Van Canneyt wrote: > [...] > I have been thinking about layout managers. I think that this should be an add-on to the currently existing layouting (to preserve delphi compatibility): > I imagine a component that one drops on a form. > One sets the 'target' control (control whose children should be managed) and some properties. > > Depending on the layout one wants, a different component must be dropped: > > TLayout > +- TAbsoluteLayout > +- THBoxLayout > +- TVBoxLayout > +- TTableLayout > +- TBorderLayout > ... > Each descendent has different properties. Changing the layout just means > dropping another component; something that can be done run-time. > > Something like this exists in ExtJS, and it works very well. > > The only thing I am unsure about is whether TControl should be made TLayout-aware. > As far as I understand, a layouter only needs to be able to handle rectangles, > within some restrictions (some callbacks to get min/max rectangles). > It need not know anything about TControl or it's properties, and as such could > be implemented totally independent of the LCL. See below. > I discussed this idea once with Mattias Gaertner, but he seems to disagree > on the TControl-unawareness, if I recall correctly. With the new autosizing it is now possible to think about layout managers. A layout manager that handles the layout of children of a TWinControl must implement the following: - a computation of the total preferred space (children plus space). At the moment this is done by TControl.CalculatePreferredSize. - a computation of the layout (position and size of each child) (AlignControls). - a computation of the size (DoAutoSize) The layouter needs access to Left, Top, Width, Height, ClientWidth, ClientHeight, ReadBounds, BaseBounds, BaseParentClientSize, AdjustSize, InvalidatePreferredSize. Optionally a layouter could layout only a subset of the children (e.g. those with Align=alCustom or only those with default Anchors). So the LCL must call instead of its own functions the layouter. Namely: DoAutoSize, AlignControl, CalculatePreferredSize, ControlsAligned, CreateControlAlignList, CustomAlignInsertBefore, CustomAlignPosition, DoAlignChildControls. One solution would be a TWinControl property Layouter. > Maybe the planned Lazarus day in the netherlands would be a good place to > discuss this and settle things once and for all :-) :) Mattias -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email

Mattias Gaertner
to Birger Jansen
Show quoted text 7 lines
Sorry for dropping into the discussion... There is a very good LAyoutControl in the DevExpress suite (Delphi controls). We use it for a lot of projects. I think it is an excellent example of how a layout manager could work in the ideal world: http://www.devexpress.com/Products/VCL/ExLayoutControl/

This is not a layout manager, but a very nice designer extension.

If you want to see some specific examples let me know.

Mattias

Reply by email

Paul Breneman
to Michael Van Canneyt: See: http://www.blaisepascal.eu/ 26 june 2010 in the neighbourhood of Utrecht. Michael.

Michael,

http://www.blaisepascal.eu/ 26 june 2010 in the neighbourhood of Utrecht.

Does anyone have more information on the "Lazarus Controller" shown on this page?
http://www.blaisepascal.eu/index.php?actie=./lazarus_dutch_event

Regards, Paul Breneman www.dbReplication.com - VCL database replication components www.TurboControl.com - Hardware and software development services - Educational programming project for environment monitoring - Information on using FreePascal for embedded systems - Support information for the TurboPower open source libraries

Reply by email

Michael Van Canneyt
to Paul Breneman
Paul Breneman wrote 10 lines
Michael, > http://www.blaisepascal.eu/ > > 26 june 2010 in the neighbourhood of Utrecht. Does anyone have more information on the "Lazarus Controller" shown on this page? http://www.blaisepascal.eu/index.php?actie=./lazarus_dutch_event

It is described in Blaise Pascal magazine issue 10.

Basically, it is a print card with some ports and a display on it; You can write a small program in Object Pascal using Delphi/Lazarus, which you can then flash to the card's controller. I think there are some utility units which allow to control the various components on the card.

At least, that's how I had it described to me, I never used it. I think you should contact Anton Vogelaar: www.vogelaar-electronics.com.

Michael.

Show quoted text 15 lines
-- Regards, Paul Breneman www.dbReplication.com - VCL database replication components www.TurboControl.com - Hardware and software development services - Educational programming project for environment monitoring - Information on using FreePascal for embedded systems - Support information for the TurboPower open source libraries -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email

Hans-Peter Diettrich
to Michael Van Canneyt: A small follow-up on this: 1. What code is needed or can be used in Lazarus ? In the…
Show quoted text 8 lines
A small follow-up on this: 1. What code is needed or can be used in Lazarus ? In the OnDockDrop event, The width/height of the control which will be docked are no longer available. (they are 0, with the latest lazarus, no -dOldAutoSize, and the panel to dock on has height/width 0 depending on alignment)

The size should be retained, as was with old autosize. When docking is aborted, the size has to be unchanged.

Show quoted text 5 lines
2. The EasyDocManager MakeSite and SiteTest projects fail to load (TDockSite base class not available), and easyeditor crashes when run and 'open file' is used. Maybe this can be fixed.

Much has changed in the LCL since I last tested these projects :-(

I forgot to drop SiteTest, use ide_demo/MiniIDE instead. MakeSite should work, though.

DoDi

Reply by email

Hans-Peter Diettrich
to Michael Van Canneyt: That is the same as what I am saying, only the arrow points in the opposite direction. I…
Show quoted text 13 lines
>> I have been thinking about layout managers. I think that this should >> be an add-on >> to the currently existing layouting (to preserve delphi >> compatibility): I imagine a component that one drops on a form. One >> sets the 'target' control (control whose children should be managed) >> and some properties. > > I imagine a Layout property for TWinControls, or an intermediate > layer, that is initialized to the Delphi compatible manager. That > property then can be assigned any other layout manager. That is the same as what I am saying, only the arrow points in the opposite direction. I want to avoid this extra TWinControl property.

I wonder how you want LCL code to use a dropped layout component. When no predefined property exists, every TWinControl had to be searched for an according component, whenever a layout method or property shall be accessed.

With a dedicated LayoutManager property, all anchor-docking related stuff could be moved from TWinControl into the AnchoredLayoutManager, and DockManager could be replaced (or merged with) the LayoutManager. In further steps the DockClient list could be removed, the Controls list can be used instead. Delphi compatibility can be maintained by delegation to the still existing elements.

Show quoted text 8 lines
> The layout should take into account the standard TControl properties, > including alignment, constraints and anchors. It also should use the > layout managers of child controls, for forward/backward transfer of > autosize information. This is *exactly* what I want to avoid. - Either one uses the 'ordinary' delphi properties, and only those.

This shall be the default, when no dedicated manager is specified for a TWinControl.

- Or one uses layouters.

When a special manager is installed for a TWinControl.

But not a mixture of both, which will be a source of implementation/usage problems and confusion.

What should be complicated, when the Delphi layout manager is one of multiple available managers? How do you want to implement different layout management for parts of a form?

IMO the autosize woes only result from the overcomplicated handling of multiple layout models at the same time (Delphi compatible and Lazarus anchor "docking" management).

Keep it simple.

I *only* want to simplify everything. When every TWinControl now can have an DockManager, it will have an LayoutManager after the redesign. That manager will allow to manage the layout of every TWinControl independently, and the extra code for resizing DockSites can be removed.

The default manager will be the Delphi compatible one, that can continue to reside in TWinControl, when no other manager has been installed; or it can be moved into the TLayoutManager base class, or into a descendant of that class.

Show quoted text 7 lines
Once this split works correctly, you can always later try to create a TLayout descendent which tries to mimic Delphi behaviour, taking into account all TControl/TWincontrol properties; Then remove all old code and insert the new layouter. In my opinion, this approach guarantees has a bigger chance of success than immediatly trying to do everything at once...

I don't understand what you want to separate - but perhaps we mean the same thing?

DoDi

Reply by email

Marco van de Voort
to Paul Breneman: The information at that link made things clear. Thanks! Paul
Paul Breneman wrote
> At least, that's how I had it described to me, I never used it. I think > you should contact Anton Vogelaar: www.vogelaar-electronics.com. The information at that link made things clear. Thanks!

Vogelaar electronics used to use AVR chips (for the delphi stamp), and they had an own pascal compiler for it.

The used lingo "simulated using lazarus" leads me to believe this is still the case (IOW it is not FPC compiled what runs on that board, the PC development side of it is probably using FPC)

Reply by email

Michael Van Canneyt
to Hans-Peter Diettrich: I wonder how you want LCL code to use a dropped layout component. When no predefined…
Hans-Peter Diettrich wrote 18 lines
Michael Van Canneyt schrieb: >>> I have been thinking about layout managers. I think that this should be >>> an add-on >>> to the currently existing layouting (to preserve delphi compatibility): I >>> imagine a component that one drops on a form. One sets the 'target' >>> control (control whose children should be managed) and some properties. >> >> I imagine a Layout property for TWinControls, or an intermediate layer, >> that is initialized to the Delphi compatible manager. That property then >> can be assigned any other layout manager. > > That is the same as what I am saying, only the arrow points in the opposite > direction. I want to avoid this extra TWinControl property. I wonder how you want LCL code to use a dropped layout component. When no predefined property exists, every TWinControl had to be searched for an according component, whenever a layout method or property shall be accessed.

I would use a mechanism similar to the datalink. As soon as you tell the layout manager to manage a certain control, a hook is installed in the control.

Show quoted text 7 lines
With a dedicated LayoutManager property, all anchor-docking related stuff could be moved from TWinControl into the AnchoredLayoutManager, and DockManager could be replaced (or merged with) the LayoutManager. In further steps the DockClient list could be removed, the Controls list can be used instead. Delphi compatibility can be maintained by delegation to the still existing elements.

The reason I don't want to introduce the layoutmanager property is that it simply does not make sense for all TWinControls. a TEdit does not need a layoutmanager, only the parent of the TEdit needs one.

Show quoted text 22 lines
>> The layout should take into account the standard TControl properties, >> including alignment, constraints and anchors. It also should use the >> layout managers of child controls, for forward/backward transfer of >> autosize information. > > This is *exactly* what I want to avoid. > > - Either one uses the 'ordinary' delphi properties, and only those. This shall be the default, when no dedicated manager is specified for a TWinControl. > - Or one uses layouters. When a special manager is installed for a TWinControl. > But not a mixture of both, which will be a source of implementation/usage > problems and confusion. What should be complicated, when the Delphi layout manager is one of multiple available managers? How do you want to implement different layout management for parts of a form?

Simply drop 2 layouters, and point them to the right parts of the form.

Show quoted text 26 lines
IMO the autosize woes only result from the overcomplicated handling of multiple layout models at the same time (Delphi compatible and Lazarus anchor "docking" management). > Keep it simple. I *only* want to simplify everything. When every TWinControl now can have an DockManager, it will have an LayoutManager after the redesign. That manager will allow to manage the layout of every TWinControl independently, and the extra code for resizing DockSites can be removed. The default manager will be the Delphi compatible one, that can continue to reside in TWinControl, when no other manager has been installed; or it can be moved into the TLayoutManager base class, or into a descendant of that class. > Once this split works correctly, you can always later try to create a > TLayout descendent which tries to mimic Delphi behaviour, taking into > account all TControl/TWincontrol properties; Then remove all old code > and insert the new layouter. > > In my opinion, this approach guarantees has a bigger chance of success than > immediatly trying to do everything at once... I don't understand what you want to separate - but perhaps we mean the same thing?

I think we mean the same thing, it's just some details that are different... :-)

Michael.

Reply by email

Mattias Gaertner
to Michael Van Canneyt
Show quoted text 26 lines
On Tue, 6 Apr 2010, Hans-Peter Diettrich wrote: > Michael Van Canneyt schrieb: > >>>> I have been thinking about layout managers. I think that this should be >>>> an add-on >>>> to the currently existing layouting (to preserve delphi compatibility): I >>>> imagine a component that one drops on a form. One sets the 'target' >>>> control (control whose children should be managed) and some properties. >>> >>> I imagine a Layout property for TWinControls, or an intermediate layer, >>> that is initialized to the Delphi compatible manager. That property then >>> can be assigned any other layout manager. >> >> That is the same as what I am saying, only the arrow points in the opposite >> direction. I want to avoid this extra TWinControl property. > > I wonder how you want LCL code to use a dropped layout component. When no > predefined property exists, every TWinControl had to be searched for an > according component, whenever a layout method or property shall be accessed. I would use a mechanism similar to the datalink. As soon as you tell the layout manager to manage a certain control, a hook is installed in the control.

And where is the hook stored?

Show quoted text 11 lines
> > With a dedicated LayoutManager property, all anchor-docking related stuff > could be moved from TWinControl into the AnchoredLayoutManager, and > DockManager could be replaced (or merged with) the LayoutManager. In further > steps the DockClient list could be removed, the Controls list can be used > instead. Delphi compatibility can be maintained by delegation to the still > existing elements. The reason I don't want to introduce the layoutmanager property is that it simply does not make sense for all TWinControls. a TEdit does not need a layoutmanager, only the parent of the TEdit needs one.

Then don't publish it for TEdit.

[...]

Mattias

Reply by email

Michael Van Canneyt
to Mattias Gaertner
Mattias Gaertner wrote 31 lines
On Tue, 6 Apr 2010 10:48:58 +0200 (CEST) Michael Van Canneyt wrote: > > > On Tue, 6 Apr 2010, Hans-Peter Diettrich wrote: > >> Michael Van Canneyt schrieb: >> >>>>> I have been thinking about layout managers. I think that this should be >>>>> an add-on >>>>> to the currently existing layouting (to preserve delphi compatibility): I >>>>> imagine a component that one drops on a form. One sets the 'target' >>>>> control (control whose children should be managed) and some properties. >>>> >>>> I imagine a Layout property for TWinControls, or an intermediate layer, >>>> that is initialized to the Delphi compatible manager. That property then >>>> can be assigned any other layout manager. >>> >>> That is the same as what I am saying, only the arrow points in the opposite >>> direction. I want to avoid this extra TWinControl property. >> >> I wonder how you want LCL code to use a dropped layout component. When no >> predefined property exists, every TWinControl had to be searched for an >> according component, whenever a layout method or property shall be accessed. > > I would use a mechanism similar to the datalink. As soon as you tell the > layout manager to manage a certain control, a hook is installed in the > control. And where is the hook stored?

In TWinControl, protected or even private.

Show quoted text 12 lines
>> With a dedicated LayoutManager property, all anchor-docking related stuff >> could be moved from TWinControl into the AnchoredLayoutManager, and >> DockManager could be replaced (or merged with) the LayoutManager. In further >> steps the DockClient list could be removed, the Controls list can be used >> instead. Delphi compatibility can be maintained by delegation to the still >> existing elements. > > The reason I don't want to introduce the layoutmanager property is that it > simply does not make sense for all TWinControls. a TEdit does not need a > layoutmanager, only the parent of the TEdit needs one. Then don't publish it for TEdit.

I understand this, I thought of this also.
But I think it is more clean if the hook is hidden completely; This way one cannot 'forget' to publish it or publish it when it is not needed.

Finally, it doesn't really matter. To my taste, my solution is cleaner.

Opinions may vary on what 'clean' is, of course :-)

Michael.

Reply by email

Mattias Gärtner
to Michael Van Canneyt

Zitat von Michael Van Canneyt :

Show quoted text 8 lines
[...] >> I would use a mechanism similar to the datalink. As soon as you tell the >> layout manager to manage a certain control, a hook is installed in the >> control. > > And where is the hook stored? In TWinControl, protected or even private.

And how to find out which layout a control uses?

[...] > Then don't publish it for TEdit.

Btw, even a TEdit can need a layout to store extra properties, for autosizing itself, for special docking, for alignment or for designer specials.

Show quoted text 8 lines
I understand this, I thought of this also. But I think it is more clean if the hook is hidden completely; This way one cannot 'forget' to publish it or publish it when it is not needed. Finally, it doesn't really matter. To my taste, my solution is cleaner. Opinions may vary on what 'clean' is, of course :-)

Your solution seems somewhat limited to the ExtJS layouts.

Mattias

Reply by email

Martin
to Michael Van Canneyt: In TWinControl, protected or even private. I understand this, I thought of this also. But…
Michael Van Canneyt wrote 28 lines
>>> With a dedicated LayoutManager property, all anchor-docking related >>> stuff >>> could be moved from TWinControl into the AnchoredLayoutManager, and >>> DockManager could be replaced (or merged with) the LayoutManager. >>> In further >>> steps the DockClient list could be removed, the Controls list can >>> be used >>> instead. Delphi compatibility can be maintained by delegation to >>> the still >>> existing elements. >> >> The reason I don't want to introduce the layoutmanager property is >> that it >> simply does not make sense for all TWinControls. a TEdit does not >> need a >> layoutmanager, only the parent of the TEdit needs one. > > Then don't publish it for TEdit. I understand this, I thought of this also. But I think it is more clean if the hook is hidden completely; This way one cannot 'forget' to publish it or publish it when it is not needed. Finally, it doesn't really matter. To my taste, my solution is cleaner. Opinions may vary on what 'clean' is, of course :-)

Hm, but something I am missing.

I see why it would be nice to avoid a published hook at all (never mind if it is a Layouter property, or an OnLayout event).

I can see that work, if a Layouter was always global => drop it on a Form, and the Layouter will grab control of all controls on the Form.

But if you want selective Autosizing (eg, just PanelX should use the Layouter, the rest uses the default, or yet another Layouter), then the user needs to configure this.

Either you need a special property editor, which opens for the Layouter, and allows you to add/remove controls. Or you have a Layouter property. IMHO the property would be fine in this case.

Martin
Or am I missing a 3rd way?

Reply by email

Alexander Klenin
to Martin
Martin wrote 13 lines
I can see that work, if a Layouter was always global => drop it on a Form, and the Layouter will grab control of all controls on the Form. But if you want selective Autosizing (eg, just PanelX should use the Layouter, the rest uses the default, or yet another Layouter), then the user needs to configure this. Either you need a special property editor, which opens for the Layouter, and allows you to add/remove controls. Or you have a Layouter property. IMHO the property would be fine in this case. Martin Or am I missing a 3rd way?

How about Layouter grabbing control of its Parent? So you can put it on the panel, and it will guide the layout of all child controls of that panel --
seems logical to me.

Alexander S. Klenin

Reply by email

Michael Van Canneyt
to Mattias Gärtner: Zitat von Michael Van Canneyt : And how to find out which layout a control uses? Btw,…
Mattias G?rtner wrote 12 lines
Zitat von Michael Van Canneyt : > [...] >>> I would use a mechanism similar to the datalink. As soon as you tell the >>> layout manager to manage a certain control, a hook is installed in the >>> control. >> >> And where is the hook stored? > > In TWinControl, protected or even private. And how to find out which layout a control uses?

The control has no need to know which layout it uses. It just needs to know that it must handle positioning/sizing over to the layout. (through the hook).

Show quoted text 5 lines
> [...] >> Then don't publish it for TEdit. Btw, even a TEdit can need a layout to store extra properties, for autosizing itself, for special docking, for alignment or for designer specials.

I don't believe this should be so.
If this is so, then the layouting is badly designed.

Show quoted text 10 lines
> I understand this, I thought of this also. But I think it is more clean if > the hook is hidden completely; This > way one cannot 'forget' to publish it or publish it when it is not > needed. > > Finally, it doesn't really matter. To my taste, my solution is cleaner. > > Opinions may vary on what 'clean' is, of course :-) Your solution seems somewhat limited to the ExtJS layouts.

Maybe, but it has the advantage of being very clear and simple. And I think clarity is a virtue, for which I am prepared to sacrifice a few corner cases.

Currently, the layouting is simply a mess, with added ad-hoc properties and no clear rules that determine which property has precedence over other properties.

Michael.

Reply by email

Mattias Gärtner
to Alexander Klenin: How about Layouter grabbing control of its Parent? So you can put it on the panel, and it…

Zitat von Alexander Klenin :

Show quoted text 19 lines
On Tue, Apr 6, 2010 at 22:52, Martin wrote: > I can see that work, if a Layouter was always global => drop it on a Form, > and the Layouter will grab control of all controls on the Form. > > But if you want selective Autosizing (eg, just PanelX should use the > Layouter, the rest uses the default, or yet another Layouter), then the user > needs to configure this. > > Either you need a special property editor, which opens for the Layouter, and > allows you to add/remove controls. Or you have a Layouter property. IMHO the > property would be fine in this case. > > Martin > Or am I missing a 3rd way? How about Layouter grabbing control of its Parent? So you can put it on the panel, and it will guide the layout of all child controls of that panel -- seems logical to me.

Notes:
1. Only TControls can be put into TWinControl and a layouter is not a visual thing itself.
2. a layouter can be used by several controls.

Mattias

Reply by email

Hans-Peter Diettrich
to Michael Van Canneyt: I would use a mechanism similar to the datalink. As soon as you tell the layout manager…
Show quoted text 8 lines
> I wonder how you want LCL code to use a dropped layout component. When > no predefined property exists, every TWinControl had to be searched > for an according component, whenever a layout method or property shall > be accessed. I would use a mechanism similar to the datalink. As soon as you tell the layout manager to manage a certain control, a hook is installed in the control.

And where do you want to store layout specific information?

Show quoted text 10 lines
> With a dedicated LayoutManager property, all anchor-docking related > stuff could be moved from TWinControl into the AnchoredLayoutManager, > and DockManager could be replaced (or merged with) the LayoutManager. > In further steps the DockClient list could be removed, the Controls > list can be used instead. Delphi compatibility can be maintained by > delegation to the still existing elements. The reason I don't want to introduce the layoutmanager property is that it simply does not make sense for all TWinControls. a TEdit does not need a layoutmanager, only the parent of the TEdit needs one.

There is much stuff that doesn't make sense for all controls.

Show quoted text 5 lines
> What should be complicated, when the Delphi layout manager is one of > multiple available managers? How do you want to implement different > layout management for parts of a form? Simply drop 2 layouters, and point them to the right parts of the form.

With the result that the form is crowded with layouters :-(

Not to mention prefabricated controls, e.g. with horizontal or vertical layout.

DoDi

Reply by email

Mattias Gärtner
to Michael Van Canneyt: The control has no need to know which layout it uses. It just needs to know that it must…

Zitat von Michael Van Canneyt :

Show quoted text 18 lines
On Tue, 6 Apr 2010, Mattias G?rtner wrote: > Zitat von Michael Van Canneyt : > >> [...] >>>> I would use a mechanism similar to the datalink. As soon as you tell the >>>> layout manager to manage a certain control, a hook is installed in the >>>> control. >>> >>> And where is the hook stored? >> >> In TWinControl, protected or even private. > > And how to find out which layout a control uses? The control has no need to know which layout it uses.

How can a designer tool find out what layout a control uses?

Show quoted text 13 lines
It just needs to know that it must handle positioning/sizing over to the layout. (through the hook). >> [...] >>> Then don't publish it for TEdit. > > Btw, even a TEdit can need a layout to store extra properties, for > autosizing itself, for special docking, for alignment or for > designer specials. I don't believe this should be so. If this is so, then the layouting is badly designed.

How would you do that?
For example you want a group of TEdits to position/resize according to a policy, so you set for all your edits a layouter.

Show quoted text 14 lines
>> I understand this, I thought of this also. But I think it is more >> clean if the hook is hidden completely; This >> way one cannot 'forget' to publish it or publish it when it is not >> needed. >> >> Finally, it doesn't really matter. To my taste, my solution is cleaner. >> >> Opinions may vary on what 'clean' is, of course :-) > > Your solution seems somewhat limited to the ExtJS layouts. Maybe, but it has the advantage of being very clear and simple. And I think clarity is a virtue, for which I am prepared to sacrifice a few corner cases.

Counter example:
When I first suggested to extend the Anchors I only suggested a simple anchor to one control. AFAIR it was Marc who said, we should do that for each side. I thought: This is only useful for a very few corner cases. Nowadays we use this feature at hundreds of places in the IDE. I'm very glad that Marc had the foresight.

Currently, the layouting is simply a mess, with added ad-hoc properties and no clear rules that determine which property has precedence over other properties.

See here:
http://wiki.lazarus.freepascal.org/Autosize_/_Layout

Mattias

Reply by email

Hans-Peter Diettrich
to Martin: Hm, but something I am missing. I see why it would be nice to avoid a published hook at…
Either you need a special property editor, which opens for the Layouter, and allows you to add/remove controls. Or you have a Layouter property. IMHO the property would be fine in this case.

ACK. Like the Font property, the properties of the selected layouter can be edited in the OI as well. When in contrast the layout components are dropped into arbitrary places on the form, it's hard to find the component dedicated to a specific control.

Or am I missing a 3rd way?

We could have customized panels, for all the different layouts. But this feature is not applicable to forms, and it will be very hard to change the layout later, after a panel has been populated with child controls; then you'd also loose all other properties of the panel.

Eventually we need some more design modes, to disable automatic update of a form while editing layout details. I don't like the greedy attitude of alClient, when it comes to adding more controls around it.

DoDi

Reply by email

Hans-Peter Diettrich
to Alexander Klenin: How about Layouter grabbing control of its Parent? So you can put it on the panel, and it…
How about Layouter grabbing control of its Parent? So you can put it on the panel, and it will guide the layout of all child controls of that panel -- seems logical to me.

This method could work, of course.

But the component will consume space in the control at design time, and it also will be part of the Controls array at runtime - requiring according checks while a layout is recalculated. And it shares other possible flaws with separate layout managers, e.g. the chance for multiple managers assigned to the same control, and/or additional links between control and manager.

DoDi

Reply by email

Michael Van Canneyt
to Mattias Gärtner: Zitat von Michael Van Canneyt : How can a designer tool find out what layout a control…
Mattias G?rtner wrote 23 lines
Zitat von Michael Van Canneyt : > > > On Tue, 6 Apr 2010, Mattias G?rtner wrote: > >> Zitat von Michael Van Canneyt : >> >>> [...] >>>>> I would use a mechanism similar to the datalink. As soon as you tell the >>>>> layout manager to manage a certain control, a hook is installed in the >>>>> control. >>>> >>>> And where is the hook stored? >>> >>> In TWinControl, protected or even private. >> >> And how to find out which layout a control uses? > > The control has no need to know which layout it uses. How can a designer tool find out what layout a control uses?

Why does it need to know ?

If it needs to know what layout a control uses, the designer is flawed by design:

There may be layouters that the designer has no knowledge of, and hence if such a layouter is dropped on the form, the designer will be lost.

Show quoted text 17 lines
> It just needs to know that it must handle positioning/sizing over to > the layout. > (through the hook). > >>> [...] >>>> Then don't publish it for TEdit. >> >> Btw, even a TEdit can need a layout to store extra properties, for >> autosizing itself, for special docking, for alignment or for >> designer specials. > > I don't believe this should be so. If this is so, then the layouting > is badly designed. How would you do that? For example you want a group of TEdits to position/resize according to a policy, so you set for all your edits a layouter.

I don't see what is to store in the TEdits ?
The 'policy' is a property of the layouter, not of the TEdits.

Show quoted text 21 lines
>>> I understand this, I thought of this also. But I think it is more >>> clean if the hook is hidden completely; This >>> way one cannot 'forget' to publish it or publish it when it is not >>> needed. >>> >>> Finally, it doesn't really matter. To my taste, my solution is cleaner. >>> >>> Opinions may vary on what 'clean' is, of course :-) >> >> Your solution seems somewhat limited to the ExtJS layouts. > > Maybe, but it has the advantage of being very clear and simple. > And I think clarity is a virtue, for which I am prepared to sacrifice > a few corner cases. Counter example: When I first suggested to extend the Anchors I only suggested a simple anchor to one control. AFAIR it was Marc who said, we should do that for each side. I thought: This is only useful for a very few corner cases. Nowadays we use this feature at hundreds of places in the IDE. I'm very glad that Marc had the foresight.

No problem when using layouters: just create/adapt a new layouter class.

The simplicity and clarity is the following:

Layouter: Layouter manages everything. Each layouter has a few simple properties that determine it's (and only it's) behaviour, and no more.

Now the TControl/TWinControl classes have a set of properties that is the union of all properties of a large set of layouters (because it must mimic the behaviour of all these layouters put together):
* AutoSize
* Anchors
* Align
* Constraints
* BorderSpacing
* ChildSizing

In difference, each layouter would have only the properties that it needs to implement it's behaviour. That is simple to understand.

Show quoted text 6 lines
> Currently, the layouting is simply a mess, with added ad-hoc properties > and no clear rules that determine which property has precedence over > other properties. See here: http://wiki.lazarus.freepascal.org/Autosize_/_Layout

I find the concept of a layouter with 1 or 2 properties more clear than all these properties thrown together.

Michael.

Reply by email

Michael Van Canneyt
to Hans-Peter Diettrich: And where do you want to store layout specific information? There is much stuff that…
Hans-Peter Diettrich wrote 12 lines
Michael Van Canneyt schrieb: >> I wonder how you want LCL code to use a dropped layout component. When no >> predefined property exists, every TWinControl had to be searched for an >> according component, whenever a layout method or property shall be >> accessed. > > I would use a mechanism similar to the datalink. As soon as you tell the > layout manager to manage a certain control, a hook is installed in the > control. And where do you want to store layout specific information?

In the layout component, obviously. Where it belongs.

It does not belong in the control. If you use a layouter, all control is passed to the layouter, and hence also all extra information needed to realize the layout.

Show quoted text 12 lines
>> With a dedicated LayoutManager property, all anchor-docking related stuff >> could be moved from TWinControl into the AnchoredLayoutManager, and >> DockManager could be replaced (or merged with) the LayoutManager. In >> further steps the DockClient list could be removed, the Controls list can >> be used instead. Delphi compatibility can be maintained by delegation to >> the still existing elements. > > The reason I don't want to introduce the layoutmanager property is that it > simply does not make sense for all TWinControls. a TEdit does not need a > layoutmanager, only the parent of the TEdit needs one. There is much stuff that doesn't make sense for all controls.

That should be a good reason for not adding more stuff.

Show quoted text 7 lines
>> What should be complicated, when the Delphi layout manager is one of >> multiple available managers? How do you want to implement different layout >> management for parts of a form? > > Simply drop 2 layouters, and point them to the right parts of the form. With the result that the form is crowded with layouters :-(

I would be very surprised to see more than 4 layouters on a form. Most forms will have a single TTableLayout or TBorderLayout component, and that's it.

Not to mention prefabricated controls, e.g. with horizontal or vertical layout.

I don't understand what you mean here.

Michael.

Reply by email

Alexander Klenin
to Michael Van Canneyt
1. Only TControls can be put into TWinControl and a layouter is not a visual thing itself. 2. a layouter can be used by several controls.

Ok, I agree with Michael and Mattias that a separate layout component and a TWinControl.Layout property is the only way that satisfies all the requirements.

>>Simply drop 2 layouters, and point them to the right parts of the form. >With the result that the form is crowded with layouters :-( I would be very surprised to see more than 4 layouters on a form. Most forms will have a single TTableLayout or TBorderLayout component, and that's it.

I think one possibility to avoid excessive number of Layouters is to create a concept
of "built-in" layouter for each component.
If chosen appropriately, such layouter may serve as a good default for simple application,
as well as provide backwards compatibility with the current implementation. Anyone interested may /
TChartSeries.FBuiltinSource fields
in TAChart component for an example.

The only inconvenience is that Object Inspector and streaming subsystem currently do not
fully support editing of properties of such built-in component, but I think that
is not too hard to add.

Alexander S. Klenin

Reply by email

Martin
to Alexander Klenin
Alexander Klenin wrote 7 lines
> 1. Only TControls can be put into TWinControl and a layouter is not a visual thing itself. > 2. a layouter can be used by several controls. > Ok, I agree with Michael and Mattias that a separate layout component and a TWinControl.Layout property is the only way that satisfies all the requirements.

It is also the intuitive way. Any other control like this (that is not displaying as part of the form / popupmenu, filedialogs) are dropped on the Form, and *not* parented (childed) to any control in the form.

Popupmenus are also assigned via a property. => that is what users will expect.
Same for Datasources, on a DBGrid, etc

Martin

Reply by email

Martin
to Alexander Klenin: Ok, I agree with Michael and Mattias that a separate layout component and a…
Alexander Klenin wrote 17 lines
I think one possibility to avoid excessive number of Layouters is to create a concept of "built-in" layouter for each component. If chosen appropriately, such layouter may serve as a good default for simple application, as well as provide backwards compatibility with the current implementation. Anyone interested may / TChartSeries.FBuiltinSource fields in TAChart component for an example. The only inconvenience is that Object Inspector and streaming subsystem currently do not fully support editing of properties of such built-in component, but I think that is not too hard to add.

I hadn't had quite an exact look. But I assume FBuiltinSource can be assigned different sub-classes?

SynEdit streams something like this => look a the gutter implementation

Martin

Reply by email

Hans-Peter Diettrich
to Michael Van Canneyt: In the layout component, obviously. Where it belongs. It does not belong in the control.…
> There is much stuff that doesn't make sense for all controls. That should be a good reason for not adding more stuff.

... and to remove existing specific layout stuff.

Show quoted text 11 lines
>>> What should be complicated, when the Delphi layout manager is one of >>> multiple available managers? How do you want to implement different >>> layout management for parts of a form? >> >> Simply drop 2 layouters, and point them to the right parts of the form. > > With the result that the form is crowded with layouters :-( I would be very surprised to see more than 4 layouters on a form. Most forms will have a single TTableLayout or TBorderLayout component, and that's it.

How do you know?

> Not to mention prefabricated controls, e.g. with horizontal or > vertical layout. I don't understand what you mean here.

Many widgetsets support controls for specific layouts. Shouldn't Lazarus try to use just these controls?

DoDi

Reply by email

Michael Van Canneyt
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 22 lines
Michael Van Canneyt schrieb: >> There is much stuff that doesn't make sense for all controls. > > That should be a good reason for not adding more stuff. ... and to remove existing specific layout stuff. >>>> What should be complicated, when the Delphi layout manager is one of >>>> multiple available managers? How do you want to implement different >>>> layout management for parts of a form? >>> >>> Simply drop 2 layouters, and point them to the right parts of the form. >> >> With the result that the form is crowded with layouters :-( > > I would be very surprised to see more than 4 layouters on a form. > Most forms will have a single TTableLayout or TBorderLayout component, and > that's it. How do you know?

Simple experience. Most controls will not have a need for a layouter, but can rely on the default behaviour (absolute positioning), for which no layouter is needed.

In the few cases that I needed a "layout", it was borderlayout: a grid which is 'alClient', and a panel with Align=pbottom (in borderlayout speak: grid is center region, panel is south region).

Inside the panel the controls are arranged using table layout. So: 2 layouters.

Show quoted text 8 lines
>> Not to mention prefabricated controls, e.g. with horizontal or vertical >> layout. > > I don't understand what you mean here. Many widgetsets support controls for specific layouts. Shouldn't Lazarus try to use just these controls?

Sorry, but I still don't understand :( Please give an example ?

Michael.

Reply by email

Alexander Klenin
to Martin: I hadn't had quite an exact look. But I assume FBuiltinSource can be assigned different…
Martin wrote
I hadn't had quite an exact look. But I assume ?FBuiltinSource can be assigned different sub-classes?

Not quite -- TChartSeries.Source may be assigned either FBuiltinSource or one of different subclasses.

SynEdit streams something like this => look a the gutter implementation

Heh, it is quite interesting because I have just implemented almost the same thing myself -- compare to TChartToolset and TChartAxistransformations.

However, it is a list of objects of different classes (too bad TCollection does not support this), not what I talked about.

I talked about a property that can either refer to a usual "external" component, or a component built into the object itself.

Alexander S. Klenin

Reply by email

Hans-Peter Diettrich
to Michael Van Canneyt: Simple experience. Most controls will not have a need for a layouter, but can rely on the…
Show quoted text 7 lines
>> I would be very surprised to see more than 4 layouters on a form. >> Most forms will have a single TTableLayout or TBorderLayout >> component, and that's it. > > How do you know? Simple experience.

AFAIR the IDE is a counter example.

Most controls will not have a need for a layouter, but can rely on the default behaviour (absolute positioning), for which no layouter is needed.

This case is trivial.

In the few cases that I needed a "layout", it was borderlayout: a grid which is 'alClient', and a panel with Align=pbottom (in borderlayout speak: grid is center region, panel is south region).

That's the standard (Delphi) layouter as well.

Inside the panel the controls are arranged using table layout. So: 2 layouters.

Other application forms (settings dialogs...) contain many more controls, within multiple containers with specific layouts.

Show quoted text 9 lines
>>> Not to mention prefabricated controls, e.g. with horizontal or >>> vertical layout. >> >> I don't understand what you mean here. > > Many widgetsets support controls for specific layouts. Shouldn't > Lazarus try to use just these controls? Sorry, but I still don't understand :( Please give an example ?

Look at the gtk2 widgetset.

DoDi

Reply by email

Felipe Monteiro de Carvalho
to Hans-Peter Diettrich: ... and to remove existing specific layout stuff. How do you know? Many widgetsets…
Hans-Peter Diettrich wrote
Many widgetsets support controls for specific layouts. Shouldn't Lazarus try to use just these controls?

No, that would a horrible mess and terrible to maintain.

At least for controls there are good reasons to use native controls and loose the easiless of implementing one solution for everywhere, like accessibility and native look. But for a layouter, which has no visible parts, implementing it with native controls would be just waste of time, because you need to maintain various connections to native layouters as well as a non-native layouter for platforms without one, while just the non-native one would do the job as good as or even better for all platforms with 1 implementation.

Felipe Monteiro de Carvalho

Reply by email

Mattias Gaertner
to Michael Van Canneyt: Why does it need to know ? If it needs to know what layout a control uses, the designer…
Show quoted text 11 lines
[...] > How can a designer tool find out what layout a control uses? Why does it need to know ? If it needs to know what layout a control uses, the designer is flawed by design: There may be layouters that the designer has no knowledge of, and hence if such a layouter is dropped on the form, the designer will be lost.

I can't follow you here.
For example: I dropped several layouters on my form. Now I want to know what layouter my Panel1 uses. But I can't find out because that would be flawed by design?
Maybe you can give some more details how you want to setup the layouts in the designer.

Show quoted text 7 lines
[...] > How would you do that? > For example you want a group of TEdits to position/resize according to > a policy, so you set for all your edits a layouter. I don't see what is to store in the TEdits ? The 'policy' is a property of the layouter, not of the TEdits.

The reference to the layouter should be stored in the TEdits. For example: the layouter of Edit1 is Layout1. It does not matter what specific type Layout1 is.

Show quoted text 17 lines
[...] No problem when using layouters: just create/adapt a new layouter class. The simplicity and clarity is the following: Layouter: Layouter manages everything. Each layouter has a few simple properties that determine it's (and only it's) behaviour, and no more. Now the TControl/TWinControl classes have a set of properties that is the union of all properties of a large set of layouters (because it must mimic the behaviour of all these layouters put together): * AutoSize * Anchors * Align * Constraints * BorderSpacing * ChildSizing

Only Align, Anchors and ChildSizing.Layout are layouts. The rest are details that apply to all layouts. See the layouters of gtk.

In difference, each layouter would have only the properties that it needs to implement it's behaviour. That is simple to understand.

Yes, but not as simple to use.
For example I know many students using the java layouter. They are seldom happy with the result and often use a fixed layout and program anchors.
Layouters are easy to program and easy to explain but awkward to create nice designs.

Show quoted text 9 lines
>> Currently, the layouting is simply a mess, with added ad-hoc properties >> and no clear rules that determine which property has precedence over >> other properties. > > See here: > http://wiki.lazarus.freepascal.org/Autosize_/_Layout I find the concept of a layouter with 1 or 2 properties more clear than all these properties thrown together.

Of course.
But in the end the important part is a simple GUI to use the layouts.

Mattias

Reply by email

Michael Van Canneyt
to Mattias Gaertner
Mattias Gaertner wrote 19 lines
On Tue, 6 Apr 2010 15:33:54 +0200 (CEST) Michael Van Canneyt wrote: > [...] >> How can a designer tool find out what layout a control uses? > > Why does it need to know ? > > If it needs to know what layout a control uses, the designer is flawed by > design: > > There may be layouters that the designer has no knowledge of, and > hence if such a layouter is dropped on the form, the designer will > be lost. I can't follow you here. For example: I dropped several layouters on my form. Now I want to know what layouter my Panel1 uses. But I can't find out because that would be flawed by design?

Nono, I misunderstood your question. I thought that you wanted to know whether the designer can find out if the panel uses THBoxLayout or TTableLayout or whatever.

Maybe you can give some more details how you want to setup the layouts in the designer.

See below.

Show quoted text 12 lines
> [...] >> How would you do that? >> For example you want a group of TEdits to position/resize according to >> a policy, so you set for all your edits a layouter. > > I don't see what is to store in the TEdits ? > The 'policy' is a property of the layouter, not of the TEdits. The reference to the layouter should be stored in the TEdits. For example: the layouter of Edit1 is Layout1. It does not matter what specific type Layout1 is.

Aha. Agreed.
I see that for easy use in the IDE, the reference to the layouter should be stored in the control itself, so the user can quickly find out what the layouter is.

Show quoted text 20 lines
> [...] > No problem when using layouters: just create/adapt a new layouter class. > > The simplicity and clarity is the following: > > Layouter: Layouter manages everything. Each layouter has a few simple > properties that determine it's (and only it's) behaviour, and no more. > > Now the TControl/TWinControl classes have a set of properties that is the > union of all properties of a large set of layouters (because it must mimic > the behaviour of all these layouters put together): > * AutoSize > * Anchors > * Align > * Constraints > * BorderSpacing > * ChildSizing Only Align, Anchors and ChildSizing.Layout are layouts. The rest are details that apply to all layouts. See the layouters of gtk.

In my view, this is not correct. Borderspacing, Constraints and AutoSize are also properties used in layouting. I see no reason why a control would have these properties (assuming we were to move all layouting to a separate component).

Show quoted text 7 lines
> In difference, each layouter would have only the properties that it > needs to implement it's behaviour. That is simple to understand. Yes, but not as simple to use. For example I know many students using the java layouter. They are seldom happy with the result and often use a fixed layout and program anchors.

Maybe the Java layouter is simply no good ?

Layouters are easy to program and easy to explain but awkward to create nice designs.

If one of the layouters provides the behaviour we have now, I see no problem ?

Show quoted text 12 lines
>>> Currently, the layouting is simply a mess, with added ad-hoc properties >>> and no clear rules that determine which property has precedence over >>> other properties. >> >> See here: >> http://wiki.lazarus.freepascal.org/Autosize_/_Layout > > I find the concept of a layouter with 1 or 2 properties more clear > than all these properties thrown together. Of course. But in the end the important part is a simple GUI to use the layouts.

This, I agree on, and that is why we are discussing it so long :-)

Michael.

Reply by email

Hans-Peter Diettrich
to Michael Van Canneyt
Show quoted text 19 lines
>> Now the TControl/TWinControl classes have a set of properties that is >> the >> union of all properties of a large set of layouters (because it must >> mimic >> the behaviour of all these layouters put together): >> * AutoSize >> * Anchors >> * Align >> * Constraints >> * BorderSpacing >> * ChildSizing > > Only Align, Anchors and ChildSizing.Layout are layouts. The rest are > details that apply to all layouts. See the layouters of gtk. In my view, this is not correct. Borderspacing, Constraints and AutoSize are also properties used in layouting. I see no reason why a control would have these properties (assuming we were to move all layouting to a separate component).

IMO it's quite simple. A layout affects the position of child controls inside a container control, nothing else. Borders, Constraints and Autosize are general properties of all controls, which must be handled in/by the control itself.

Show quoted text 5 lines
> For example I know many students using the java layouter. They are > seldom happy with the result and often use a fixed layout and program > anchors. Maybe the Java layouter is simply no good ?

The Java layout managers are fine, but their use requires discipline, and a concept before one starts to code or drag&drop controls onto a form. The same for any layout, regardless of how a GUI is composed or managed.

Some more ideas:

It would help beginners when some visual feedback were given by a visual GUI designer, about e.g. anchors or the direction of expansion within every frame. A simulation of other languages were fine, because English texts sometimes are 50% shorter than the same text in other languages.

All Autosize controls should have two degrees of freedom, i.e. they should be capable of splitting text, tabs or buttons into multiple lines, when the horizontal extent is limited. Every regular layout manager should manage one restricted and one free direction of extent, where it receives or determines the extent in the restricted direction itself, and returns the resulting extent in the free direction. Both the minimal and maximal extents can be returned at the same time, depending on the minimal (required) and maximal (available) extent in the restricted direction.

DoDi

Reply by email

Michael Van Canneyt
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 25 lines
Michael Van Canneyt schrieb: >>> Now the TControl/TWinControl classes have a set of properties that is the >>> union of all properties of a large set of layouters (because it must >>> mimic >>> the behaviour of all these layouters put together): >>> * AutoSize >>> * Anchors >>> * Align >>> * Constraints >>> * BorderSpacing >>> * ChildSizing >> >> Only Align, Anchors and ChildSizing.Layout are layouts. The rest are >> details that apply to all layouts. See the layouters of gtk. > > In my view, this is not correct. Borderspacing, Constraints and AutoSize > are also properties used in layouting. I see no reason why a control would > have these properties (assuming we were to move all layouting to a separate > component). IMO it's quite simple. A layout affects the position of child controls inside a container control, nothing else. Borders, Constraints and Autosize are general properties of all controls, which must be handled in/by the control itself.

I agree for Constraints, but not the other two.

It is in contradiction with what Mattias said, where he claimed that when doing layouting you must always work inside-out and outside-in. Borderspacing IS used when layouting: it determines the available space for childs inside/outside the control.

Autosize as well: if autosize is true, then the size of the control changes, and therefor the layout internal to the control, but also externally. Hence it belongs in the layouter.

IMHO a control needs only 5 properties: top/left/width,height and constraints. All the rest is layouting.

This does not mean I want to remove all these properties from the control, but I do consider all other properties part of the layouting process.

Michael.

Reply by email

Alexander Klenin
to Hans-Peter Diettrich: IMO it's quite simple. A layout affects the position of child controls inside a container…
Hans-Peter Diettrich wrote 12 lines
>> Only Align, Anchors and ChildSizing.Layout are layouts. The rest are >> details that apply to all layouts. See the layouters of gtk. > > In my view, this is not correct. Borderspacing, Constraints and AutoSize > are also properties used in layouting. I see no reason why a control would > have these properties (assuming we were to move all layouting to a > separate component). IMO it's quite simple. A layout affects the position of child controls inside a container control, nothing else. Borders, Constraints and Autosize are general properties of all controls, which must be handled in/by the control itself.

It is not quite that simple. Obviously, the layouter must take into account some control properties, like Constraints.
Also, some control properties, like Align and Constraints, are layouter-specific,
and some, like Borders, are not.
So the most correct and general (although maybe not the easiest for user) way is to separate the concept of TLayouter and TLayouterParams. The former is assigned to "container" controls like TPanel, and governs the algorithm used by the container to position it's children. The latter is assigned to all controls, and serves to store the parameters like Align,
used by parent controls layouter.

Alexander S. Klenin

Reply by email

Hans-Peter Diettrich
to Michael Van Canneyt: I agree for Constraints, but not the other two. It is in contradiction with what Mattias…
Show quoted text 11 lines
> IMO it's quite simple. A layout affects the position of child controls > inside a container control, nothing else. Borders, Constraints and > Autosize are general properties of all controls, which must be handled > in/by the control itself. I agree for Constraints, but not the other two. It is in contradiction with what Mattias said, where he claimed that when doing layouting you must always work inside-out and outside-in. Borderspacing IS used when layouting: it determines the available space for childs inside/outside the control.

The control determines its client extent from given bounds, by taking into account its specified border style. A layout manager has no idea of such borders, bevels etc., and also not of the visible rectangle of a TScrollingWindowControl.

Autosize as well: if autosize is true, then the size of the control changes, and therefor the layout internal to the control, but also externally. Hence it belongs in the layouter.

In the simplest case the layouter has not to care about control determines its required extent, based on e.g. font size and nationalized text, and reports it as its required extent. There is nothing beyond that extent that a layout manager has to know about.

Only when a control can adopt itself to different *given* extents, by e.g. breaking its content into multiple lines, a layout manager has to split the available extent into zones for the client controls. Such a layout manager would accept an extent in one direction, and calculate the resulting extent in the other direction, or spread the client controls evenly. This is a different behaviour from the beforementioned Autosize of controls with no child controls.

IMHO a control needs only 5 properties: top/left/width,height and constraints. All the rest is layouting.

You mean that every control should have borders or bevels, as specified by the layout manager? How should such a manager know about different border styles for its client controls?

DoDi

Reply by email

Michael Van Canneyt
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 18 lines
Michael Van Canneyt schrieb: >> IMO it's quite simple. A layout affects the position of child controls >> inside a container control, nothing else. Borders, Constraints and >> Autosize are general properties of all controls, which must be handled >> in/by the control itself. > > I agree for Constraints, but not the other two. > > It is in contradiction with what Mattias said, where he claimed that > when doing layouting you must always work inside-out and outside-in. > Borderspacing IS used when layouting: it determines the available space > for childs inside/outside the control. The control determines its client extent from given bounds, by taking into account its specified border style. A layout manager has no idea of such borders, bevels etc., and also not of the visible rectangle of a TScrollingWindowControl.

From

http://wiki.lazarus.freepascal.org/Autosize_/_Layout#Align_and_BorderSpacing

"The space of BorderSpacing and of the parent's ChildSizing is applied to aligned controls. The memo below has Align=alClient"

BorderSpacing has nothing to do with border style or bevels. It is an EXTRA margin. Border style and bevels determine the ClientRect of a control, and as Mattias said, they must be queried from the control itself.

Show quoted text 17 lines
> Autosize as well: if autosize is true, then the size of the control > changes, and therefor the layout internal to the control, but also > externally. Hence it belongs in the layouter. In the simplest case the layouter has not to care about control determines its required extent, based on e.g. font size and nationalized text, and reports it as its required extent. There is nothing beyond that extent that a layout manager has to know about. Only when a control can adopt itself to different *given* extents, by e.g. breaking its content into multiple lines, a layout manager has to split the available extent into zones for the client controls. Such a layout manager would accept an extent in one direction, and calculate the resulting extent in the other direction, or spread the client controls evenly. This is a different behaviour from the beforementioned Autosize of controls with no child controls.

AutoSize for a panel explicitly is about child controls, and therefor layouting.

Unfortunately Borland used AutoSize for 2 different things:
- Resize control to accomodate child controls (as e.g. in TPanel)
- To accomodate for 'native content', such as in TLabel.

They should have been separate properties. I am talking only about the first one. The second one, obviously, is only necessary for the control itself.

Show quoted text 6 lines
> IMHO a control needs only 5 properties: top/left/width,height and > constraints. All the rest is layouting. You mean that every control should have borders or bevels, as specified by the layout manager? How should such a manager know about different border styles for its client controls?

It does not need to. ClientRect is used for this.

Michael.

Reply by email

Mattias Gärtner
to Alexander Klenin: On Wed, Apr 7, 2010 at 22:47, Michael Van Canneyt Funny, I just argued exactly the other…

Zitat von Alexander Klenin :

Show quoted text 5 lines
On Wed, Apr 7, 2010 at 22:47, Michael Van Canneyt wrote: > I agree for Constraints, but not the other two. Funny, I just argued exactly the other way around ;-)

Some properties must be handled by all Layouters. For example the interface constraints (you can not resize a combobox free under windows and a scrollbar not under gtk).

The other constraint properties makes sense in all layouters too, so I recommend to use them (not reinventing the wheel). They are also applied in all LCL code. If a layouter does not like them, I recommend that it clears the constraints instead of ignoring them.

Borderspacing properties could be used too in all layouts (I can imagine) and for consistency I recommend that they are used - at least
- in a similar way. This is more a design guide line.

AnchorSides are only for fixed and Align controls. This is special to the default LCL layouter. The same for ChildSizing.

I have trouble to find the direction of this thread, so I will repeat my proposal:

Every TControl gets a property "Layouter: TLControlLayouter". TLControlLayouter gets a bunch of methods. The most important ones are CalculatePreferredSize and AlignControls. CalculatePreferredSize computes the preferred size, which the parent layouter can use. AlignControls resizes/positions the child controls according to the current bounds. If Layouter=nil then the default layouter will be used.

Mattias

Reply by email

Mattias Gärtner
to Michael Van Canneyt: From http://wiki.lazarus.freepascal.org/Autosize_/_Layout#Align_and_BorderSpacing "The…

Zitat von Michael Van Canneyt :

Show quoted text 33 lines
On Wed, 7 Apr 2010, Hans-Peter Diettrich wrote: > Michael Van Canneyt schrieb: > >>> IMO it's quite simple. A layout affects the position of child >>> controls inside a container control, nothing else. Borders, >>> Constraints and Autosize are general properties of all controls, >>> which must be handled in/by the control itself. >> >> I agree for Constraints, but not the other two. >> >> It is in contradiction with what Mattias said, where he claimed that >> when doing layouting you must always work inside-out and outside-in. >> Borderspacing IS used when layouting: it determines the available space >> for childs inside/outside the control. > > The control determines its client extent from given bounds, by > taking into account its specified border style. A layout manager > has no idea of such borders, bevels etc., and also not of the > visible rectangle of a TScrollingWindowControl. From http://wiki.lazarus.freepascal.org/Autosize_/_Layout#Align_and_BorderSpacing "The space of BorderSpacing and of the parent's ChildSizing is applied to aligned controls. The memo below has Align=alClient" BorderSpacing has nothing to do with border style or bevels. It is an EXTRA margin. Border style and bevels determine the ClientRect of a control, and as Mattias said, they must be queried from the control itself.

BorderStyle and bevels are normally the frame. The ClientRect is the inside (excluding the frame). The BoundsRect is the outside (including the frame).
BorderSpacing the is the space around a control. It is a layouter thing. The LCL layouters use the BorderSpacing properties as minimum space between the controls (BoundsRects).

>> Autosize as well: if autosize is true, then the size of the control >> changes, and therefor the layout internal to the control, but also >> externally. Hence it belongs in the layouter.

That's right. You must disable AutoSize for all child controls when using a custom layouter. Otherwise you create an endless loop.

Show quoted text 26 lines
> > In the simplest case the layouter has not to care about autosize at > all. The control determines its required extent, based on e.g. font > size and nationalized text, and reports it as its required extent. > There is nothing beyond that extent that a layout manager has to > know about. > > Only when a control can adopt itself to different *given* extents, > by e.g. breaking its content into multiple lines, a layout manager > has to split the available extent into zones for the client > controls. Such a layout manager would accept an extent in one > direction, and calculate the resulting extent in the other > direction, or spread the client controls evenly. This is a > different behaviour from the beforementioned Autosize of controls > with no child controls. AutoSize for a panel explicitly is about child controls, and therefor layouting. Unfortunately Borland used AutoSize for 2 different things: - Resize control to accomodate child controls (as e.g. in TPanel) - To accomodate for 'native content', such as in TLabel. They should have been separate properties. I am talking only about the first one. The second one, obviously, is only necessary for the control itself.

Sorry, but separating makes no sense.
Many controls consists of several parts. A Combobox of an edit field and a button. A TLabel consists of letters.

Show quoted text 8 lines
>> IMHO a control needs only 5 properties: top/left/width,height and >> constraints. All the rest is layouting. > > You mean that every control should have borders or bevels, as > specified by the layout manager? How should such a manager know > about different border styles for its client controls? It does not need to. ClientRect is used for this.

Mattias

Reply by email

Hans-Peter Diettrich
to Michael Van Canneyt: From http://wiki.lazarus.freepascal.org/Autosize_/_Layout#Align_and_BorderSpacing "The…
Show quoted text 6 lines
"The space of BorderSpacing and of the parent's ChildSizing is applied to aligned controls. The memo below has Align=alClient" BorderSpacing has nothing to do with border style or bevels. It is an EXTRA margin. Border style and bevels determine the ClientRect of a control, and as Mattias said, they must be queried from the control itself.

BorderSpacing and ChildSizing IMO are specific to an layout manager, meaningless to other layout managers. BorderSpacing IMO is equivalent to the Delphi anchors.

Unfortunately Borland used AutoSize for 2 different things: - Resize control to accomodate child controls (as e.g. in TPanel) - To accomodate for 'native content', such as in TLabel.

It's not that different. Let's separate containers from other controls:

Containers (currently) are windowed controls which can have child controls. They must not necessarily be windowed, but they may have their own layout manager.

Other controls can be windowed, depending on the widgetset(?), but are not designed to act as containers for other controls.

Both types have a method to determine their preferred size, either themselves or by asking their layout manager. When such controls are aligned or anchored, they only have one degree of freedom for autosize - this eventually must be handled in the outer layout manager, which can ignore the preferred size of its client controls.

They should have been separate properties. I am talking only about the first one. The second one, obviously, is only necessary for the control itself.

No control can have two AutoSize properties at the same time, so it's okay to have a single property - the rest is polymorphism.

Show quoted text 8 lines
>> IMHO a control needs only 5 properties: top/left/width,height and >> constraints. All the rest is layouting. > > You mean that every control should have borders or bevels, as > specified by the layout manager? How should such a manager know about > different border styles for its client controls? It does not need to. ClientRect is used for this.

The interface between controls and layout manager has to be defined. Depending on the layout type, a control can have a designed size, and a preferred size (including autosize), and it can have a forced size, with the extent in one direction determined by the container, and a final BoundsRect when the layout is finished. Every visual control must be able to calculate and return these different sizes. A layout manager uses the appropriate sizes of its client controls, in addition to eventual anchors, in order to figure out the layout, and then determines the BoundsRect of every client. Eventually the controls are allowed to adjust or align themselves within the assigned BoundsRect (cell of a stripe or grid layout), but this better should be done by the layout manager (for ChildSizing).

The "Individual cells" sizing IMO should not be supported, it only looks ugly; a user supplied alCustom handler could implement such irregular behaviour, if a user insists in such a feature. Also BoundsRectForNewParent can be dropped, it's useless in tree docking. The same for related calculations, marked as "increase chance that the width/height is kept". All this can be done in an specific DockManager, and in the current DragDockObject.

DoDi

Reply by email

Hans-Peter Diettrich
to Mattias Gärtner: Zitat von Alexander Klenin : Some properties must be handled by all Layouters. For…
Borderspacing properties could be used too in all layouts (I can imagine) and for consistency I recommend that they are used - at least - in a similar way. This is more a design guide line.

IMO BorderSpacing should be implemented using the Delphi anchors.

Clearing properties IMO is not a good idea, when the user changes the layouter later.

AnchorSides are only for fixed and Align controls. This is special to the default LCL layouter. The same for ChildSizing.

Such specific properties may be moved into the according layouter, and should not burden standard layouts with unusable or inconsistent options.

Show quoted text 9 lines
I have trouble to find the direction of this thread, so I will repeat my proposal: Every TControl gets a property "Layouter: TLControlLayouter". TLControlLayouter gets a bunch of methods. The most important ones are CalculatePreferredSize and AlignControls. CalculatePreferredSize computes the preferred size, which the parent layouter can use. AlignControls resizes/positions the child controls according to the current bounds. If Layouter=nil then the default layouter will be used.

IMO CalculatePreferredSize should have arguments (constraints), settable by the container (layouter). See my parallel mail.

Perhaps we should distinguish between "outer" layout managers, that handle almost regular (horizontal/vertical/grid) layouts, and properties that allow to position or size a control inside its determined cell. This would simplify the grid calculations, by leaving room for fine-tuning without influencing the determined layout cells.

DoDi

Reply by email

Mattias Gaertner
to Hans-Peter Diettrich: BorderSpacing and ChildSizing IMO are specific to an layout manager, meaningless to other…
Show quoted text 5 lines
Michael Van Canneyt schrieb: [...] BorderSpacing and ChildSizing IMO are specific to an layout manager, meaningless to other layout managers. BorderSpacing IMO is equivalent to the Delphi anchors.

They are not equivalent. Delphi Anchors are only the space to the parent. BorderSpacing allows to define the space between a label and an anchored button.

[...]

Mattias

Reply by email

Hans-Peter Diettrich
to Mattias Gaertner
Show quoted text 7 lines
> BorderSpacing and ChildSizing IMO are specific to an layout manager, > meaningless to other layout managers. BorderSpacing IMO is equivalent to > the Delphi anchors. They are not equivalent. Delphi Anchors are only the space to the parent. BorderSpacing allows to define the space between a label and an anchored button.

The description of BorderSpacing is not very clear, can you improve it?

In a generalized layout management every control could be adjustable inside the cell, that has been determined by the layout manager. I.e. a regular[1] layout manager would tile the client area and assign every control a cell. When required, every control can align itself inside its cell, instead of inside its parent, using the same properties. Then the fine-tuning is independent from a specific layout manager or control type.

[1] With "regular" I mean an layout manager that splits the entire client area into rectangles, maybe 1-D (horizontal, vertical) or 2-D (grid). Every rectangle can be splitted again in the same way, resulting in a tree layout; it's a matter of convenience whether the layout manager builds an entire tree, like in a dock-tree, or multiple layout managers are used for further subdividing the rectangles. Such layouts are quite easy to manage, in contrast to an arbitrary placement and anchoring of every single control within its parent or relative other controls (almost unmanaged until unmanageable).

DoDi

Reply by email

Mattias Gärtner
to Hans-Peter Diettrich

Zitat von Hans-Peter Diettrich :

Show quoted text 11 lines
Mattias Gaertner schrieb: >> BorderSpacing and ChildSizing IMO are specific to an layout >> manager, meaningless to other layout managers. BorderSpacing IMO >> is equivalent to the Delphi anchors. > > They are not equivalent. Delphi Anchors are only the space to the > parent. BorderSpacing allows to define the space between a label and an > anchored button. The description of BorderSpacing is not very clear, can you improve it?

I tried. See here:

http://wiki.lazarus.freepascal.org/Autosize_/_Layout#BorderSpacing

Show quoted text 7 lines
In a generalized layout management every control could be adjustable inside the cell, that has been determined by the layout manager. I.e. a regular[1] layout manager would tile the client area and assign every control a cell. When required, every control can align itself inside its cell, instead of inside its parent, using the same properties. Then the fine-tuning is independent from a specific layout manager or control type.

Yes, see for example here:
http://wiki.lazarus.freepascal.org/Autosize_/_Layout#Individual_cells

What is missing in the current LCL tables are column and row spans.

Show quoted text 7 lines
[1] With "regular" I mean an layout manager that splits the entire client area into rectangles, maybe 1-D (horizontal, vertical) or 2-D (grid). Every rectangle can be splitted again in the same way, resulting in a tree layout; it's a matter of convenience whether the layout manager builds an entire tree, like in a dock-tree, or multiple layout managers are used for further subdividing the rectangles.

I think multiple layouts are enough.

Such layouts are quite easy to manage, in contrast to an arbitrary placement and anchoring of every single control within its parent or relative other controls (almost unmanaged until unmanageable).

I tend to disagree. Both can be easy and both can be pain. Tables are worse when some controls should not be placed into the raster. And Anchoring misses the alignment with multiple controls. Both need a good GUI. There should be a mode to visualize Anchors in the designer for example with arrows. And for tables there should be a mode to show the borders.

Mattias

Reply by email

Hans-Peter Diettrich
to Mattias Gärtner
Show quoted text 5 lines
> The description of BorderSpacing is not very clear, can you improve it? I tried. See here: http://wiki.lazarus.freepascal.org/Autosize_/_Layout#BorderSpacing

Much better now :-)

Show quoted text 10 lines
> In a generalized layout management every control could be adjustable > inside the cell, that has been determined by the layout manager. I.e. > a regular[1] layout manager would tile the client area and assign > every control a cell. When required, every control can align itself > inside its cell, instead of inside its parent, using the same > properties. Then the fine-tuning is independent from a specific layout > manager or control type. Yes, see for example here: http://wiki.lazarus.freepascal.org/Autosize_/_Layout#Individual_cells

That's what inspired me :-)

What is missing in the current LCL tables are column and row spans.

This will complicate many things, including designers. But you're right, it would be a nice feature. Perhaps the cells of a table should be handled like tabstops in this case, where the width/height of a control's cell snaps to the next stop. This model could be merged with anchors, when the anchors are defined for the containers, instead of from controls with fixed client positions.

Show quoted text 7 lines
> Such layouts are quite easy to manage, in contrast to an arbitrary > placement and anchoring of every single control within its parent or > relative other controls (almost unmanaged until unmanageable). I tend to disagree. Both can be easy and both can be pain. Tables are worse when some controls should not be placed into the raster.

I'd call this a bad design, that does not scale well. An adjustment with BorderSpacing should be sufficient.

And Anchoring misses the alignment with multiple controls.

That's why I suggested to define "tabstops" for containers, that do not break on a resize. The tabstops can scale with the container, or they can stay anchored to an edge or the center of an container. In the most general model a Resize handler can be used to adjust the rulers.

Both need a good GUI. There should be a mode to visualize Anchors in the designer for example with arrows. And for tables there should be a mode to show the borders.

This could be done with guide-lines, replacing the uniform designer grid. Some feedback principles can be taken from docking...

DoDi

Reply by email