Sign in Join

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

Mailing lists / lazarus / 2013-08

TPairSplitter, Callback when splitter moved

5 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

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

Jürgen Hestermann

Yet another TPairSplitter question:

I can ensure that the ratio between upper and lower panel is a certain ratio by adding an OnResize method like this:

PairSplitter1.Position    := Round(PairSplitter1.Height*SplitterRatio);

with SplitterRatio beeing something between 0 and 1 (I used 0.5 to make both (nearly) the same size).

But if the user now changes the ratio manually I need to update SplitterRatio. What event is driven when the splitter is moved manually so that I can recalculate SplitterRatio?

Reply by email

Mattias Gaertner
to Jürgen Hestermann
Show quoted text 10 lines
Yet another TPairSplitter question: I can ensure that the ratio between upper and lower panel is a certain ratio by adding an OnResize method like this: PairSplitter1.Position := Round(PairSplitter1.Height*SplitterRatio); with SplitterRatio beeing something between 0 and 1 (I used 0.5 to make both (nearly) the same size). But if the user now changes the ratio manually I need to update SplitterRatio. What event is driven when the splitter is moved manually so that I can recalculate SplitterRatio?

When the splitter is moved the size of the first side is changed. So, you could use Sides[0].OnResize.

Mattias

Reply by email

Jürgen Hestermann
to Mattias Gaertner
Mattias Gaertner wrote 12 lines
On Fri, 23 Aug 2013 13:50:16 +0200 J?rgen Hestermann wrote: > I can ensure that the ratio between upper and lower panel is a certain ratio by adding an OnResize method like this: > PairSplitter1.Position := Round(PairSplitter1.Height*SplitterRatio); > with SplitterRatio beeing something between 0 and 1 (I used 0.5 to make both (nearly) the same size). > > But if the user now changes the ratio manually I need to update SplitterRatio. > What event is driven when the splitter is moved manually so that I can recalculate SplitterRatio? When the splitter is moved the size of the first side is changed. So, you could use Sides[0].OnResize.

Well, unfortunately it's not that easy.

The panel sizes are changed too when the whole form size changes. That's what I wanted it to do.
In this case the new ratio should *not* be recalculated, just the opposite: It should resize the 2 controls according to the original ratio.

So the same ratio between both sides should exist even after resizing except when resizing is caused by moving the splitter in which case a new ratio should be calculated. But OnResize is called in all cases and I can't distinguish between the user having moved the splitter or the form has changed (and I reapply the old ratio).

But I found a solution by saving the old height (or width) of the TPairSplitter component:

-------------------------------------------------------------------------------------
var SplitterHeightOld : LongInt;
procedure TForm1.PairSplitter1Resize(Sender : TObject);
begin
PairSplitter1.Position := Round(PairSplitter1.Height*SplitterRatio);
SplitterHeightOld        := PairSplitter1.Height;
end;
procedure TForm1.PairSplitterSide1Resize(Sender : TObject);
begin
if SplitterHeightOld=PairSplitter1.Height then
    SplitterRatio := PairSplitter1.Position/PairSplitter1.Height;
end;
-------------------------------------------------------------------------------------

How would I do this when using TSplitter instead of TPairSplitter? It seems I need yet another panel that contains the splitter and the 2 other controls so that I can distinguish between size change caused by change of window size or by moving the splitter.

In general, I am astonished that this kind of proportial resizing is not implemented and the default in TPairSplitter. I would think that nearly everybody wants this behaviour when two controls should share the same space. Why should one of the controls *not* grow when the windows is enlarged (or shrink when it is made smaller)? At least an event for the splitter move would be needed. Or even 2 properties "ProportialSizing" (with TRUE as default) and "SizingRatio" (with 0.5 as default).

But too bad if TPaisSplitter will be is it still there if it should be removed since so many years? I thought that internally it is built with TSplitter anyway, so why is it a problem on certain WidgetSets?

Reply by email

Mattias Gaertner
to Jürgen Hestermann
Show quoted text 19 lines
Am 2013-08-24 22:58, schrieb Mattias Gaertner: > On Fri, 23 Aug 2013 13:50:16 +0200 > J?rgen Hestermann wrote: > >> I can ensure that the ratio between upper and lower panel is a certain ratio by adding an OnResize method like this: >> PairSplitter1.Position := Round(PairSplitter1.Height*SplitterRatio); >> with SplitterRatio beeing something between 0 and 1 (I used 0.5 to make both (nearly) the same size). >> >> But if the user now changes the ratio manually I need to update SplitterRatio. >> What event is driven when the splitter is moved manually so that I can recalculate SplitterRatio? > When the splitter is moved the size of the first side is changed. So, > you could use Sides[0].OnResize. > Well, unfortunately it's not that easy. The panel sizes are changed too when the whole form size changes. That's what I wanted it to do. In this case the new ratio should *not* be recalculated, just the opposite: It should resize the 2 controls according to the original ratio.

Store the size of the first side and the pairsplitter control. In the OnResize compare last sizes with current sizes. If pairsplitter has same size, then splitter was moved. As you do below.

Show quoted text 25 lines
So the same ratio between both sides should exist even after resizing except when resizing is caused by moving the splitter in which case a new ratio should be calculated. But OnResize is called in all cases and I can't distinguish between the user having moved the splitter or the form has changed (and I reapply the old ratio). But I found a solution by saving the old height (or width) of the TPairSplitter component: ------------------------------------------------------------------------------------- var SplitterHeightOld : LongInt; procedure TForm1.PairSplitter1Resize(Sender : TObject); begin PairSplitter1.Position := Round(PairSplitter1.Height*SplitterRatio); SplitterHeightOld := PairSplitter1.Height; end; procedure TForm1.PairSplitterSide1Resize(Sender : TObject); begin if SplitterHeightOld=PairSplitter1.Height then SplitterRatio := PairSplitter1.Position/PairSplitter1.Height; end; ------------------------------------------------------------------------------------- How would I do this when using TSplitter instead of TPairSplitter?

Use Splitter.Parent.OnResize and Splitter.OnMoved.

It seems I need yet another panel that contains the splitter and the 2 other controls

Sometimes panels are needed, sometimes not. Depends on your controls and layout.

Show quoted text 6 lines
so that I can distinguish between size change caused by change of window size or by moving the splitter. In general, I am astonished that this kind of proportial resizing is not implemented and the default in TPairSplitter. I would think that nearly everybody wants this behaviour when two controls should share the same space. Why should one of the controls *not* grow when the windows is enlarged (or shrink when it is made smaller)?

Most applications have either a fixed ratio or a manually draggable splitter. You want a combination.
Feel free to implement that and send a patch. Keep in mind rounding errors, extreme cases (e.g. too small) and constraints.

At least an event for the splitter move would be needed.

What's wrong with OnMoved?

Or even 2 properties "ProportialSizing" (with TRUE as default) and "SizingRatio" (with 0.5 as default). But too bad if TPaisSplitter will be removed at all. Why is it still there if it should be removed since so many years?

It does not hurt much. The laz devels try to avoid breaking compatibility without good reason. But since new widgetsets will not support it it is marked as deprecated.

I thought that internally it is built with TSplitter anyway, so why is it a problem on certain WidgetSets?

That's the reason. It is not implemented with TSplitter, but every widgetset has to implement it.
If you implement a compatible replacement with TSplitter and two panels instead, then TPairSplitter can stay.

Mattias

Reply by email

Jürgen Hestermann
to Mattias Gaertner
Mattias Gaertner wrote
> At least an event for the splitter move would be needed. What's wrong with OnMoved?

There is no "OnMoved" in TPairSplitter (at least I can't find one). It would require to have a control for the splitter object too (which does not exist either).

It does not hurt much. The laz devels try to avoid breaking compatibility without good reason. But since new widgetsets will not support it it is marked as deprecated.

That means that I need to switch to TSplitter some day anyway, if new WidgetSets are not supported anymore.

Show quoted text 5 lines
> I thought that internally it is built with TSplitter anyway, > so why is it a problem on certain WidgetSets? That's the reason. It is not implemented with TSplitter, but every widgetset has to implement it.

Well, if I look into the code there are lots of TSplitter controls used in TPairSplitter. To me it looks that it's all based on TSplitter.
Though I don't know all the details...

Reply by email