On Tue, Jun 21, 2016 at 1:45 PM, Mattias Gaertner <
Show quoted text 19 lines
wrote:
On Tue, 21 Jun 2016 04:05:04 +0200
Martin Grajcar wrote:
>[...]Despite that, it works fine for all controls with Anchors
> = [akLeft, akTop]. For controls with other anchors, nothing works[...]
> The problem seems to lie in TControl.UpdateBaseBounds when
> the FBaseParentClientSize gets stored, which happens to be (0, 0) at this
> point. If I hack it to keep the previously stored value, it somehow
works.
BoundsRect (Left,Top,Width,Height) is the current position/size.
When a form's width is changed the LCL has to adapt the right anchored
controls - aka changing the Left so that the distance of the right
side is restored. The right distance is computed from BaseBounds
and BaseParentClientSize.
Thank you a lot for all the explanations.
That's what I'm doing now manually:
bb := AControl.BaseBounds;
bpcs := AControl.BaseParentClientSize;
OldLeft := bb.Left;
OldWidth := bb.Right - bb.Left;
// right = distance of the right edge from the *right* parent's edge
OldRight := bpcs.cx - OldLeft - OldWidth;
NewRight := OldRight; // keep it
NewWidth := OldWidth * Zoom; // scale it
NewLeft := bpcs.cx - OldRight - OldWidth;
I'm rather sure that the computation is right (the above code mayn't be, but the real one is). The problem is that not only BaseBounds gets stored, but also BaseParentClientSize, which gets taken from the actual parent, which has zero size at the moment.
What I'm doing would be right if the BaseParentClientSize were preserved. I hacked lcl/include/control.inc and got what I wanted:
procedure TControl.UpdateAnchorRules;
begin
- UpdateBaseBounds(true,true,false);
+ UpdateBaseBounds(true,false,true);
end;
This doesn't sound right... I guess, Lazarus counts on me computing the bounds relatively to the zero-size parent??? Maybe replacing the second occurrence of bpcs.cx by 0 (more exactly: the actual Parent.ClientWidth) would do? This would imply negative Left, but what...
BaseBounds/BaseParentClientSize is set when you call SetBounds (e.g.
when setting Left, Top, Width, Height).
My debugger agrees with you. I don't ask why so complicated. ;)
When the LCL computes the
autosized values it calls SetBoundsKeepBase, so it changes
BoundsRect and keeps BaseBounds/BaseParentClientSize.
Makes sense.
Show quoted text 7 lines
> The zero-client-size parent is a TPage, but I can't claim it guilty as I
> couldn't reproduce my problem in a small example.
Do you mean it does work in a small example, but it does not in your
complex application?
Exactly. I thought that there might be a bug in TNotebook/TPage leading to zero client area, but this isn't the case.
Show quoted text 28 lines
So I wonder:
>
> - Is it forbidden to change position and/or size of a component when
> it's not shown?
It is allowed and a pretty normal thing.
> - If not, how can I deal with right-aligned controls? Simply setting
> c.Left := c.Left * Factor doesn't seem to work (though it should as
in this
> step all positions and all sizes simply get scaled up; anchoring is
used
> when the parent resizes and not the component itself, right?).
Maybe you forget to disable the autosize updates during the changes?
Simple example:
MainControl.DisableAlign;
try
MainControl.SetBounds(Width*f,Height*f);
for aControl in List do
aControl.SetBounds(aControl.Left*f,aControl.Top*f,aControl.Width*f,aControl.Height*f);
finally
MainControl.EnableAlign;
end;
I sort of intentionally did not use it: I use no align and no autosize (just anchors), so I though I won't need it. Now, I included it, but I still need to hack TControl.UpdateAnchorRules as above.
Note: This algorithm has rounding errors, so multiple zooms will
destroy your layout.
I know. Currently, I don't care about a pixel or two... my layout has orders of magnitude bigger problems.
However, for the future, I'm curious if there's a simple way of storing additional information for a control without subclassing it. Let's say, I need to store the *original* font size of *every* control. And I don't want to run to any problems when the control gets freed.
Regards, Martin.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20160623/36a97234/attachment-0001.html>