I need help to implement control scaling (by ScaleBy method) with trackbar.
Here's my OnChange event for trackbar but it does not work perfectly:
procedure TMainForm.tbScaleChange(Sender: TObject);
begin
if tbScale.Tag = 0 then
begin
// this section is to make trackbar's step = 5
tbScale.Tag := 1;
if tbScale.Position mod 5 <> 0 then
tbScale.Position := 5 * ((tbScale.Position + 5 div 2) div 5);
tbScale.Tag := 0;
// in FtbScalePrevPos form variable I keep previous trackbar position
if FtbScalePrevPos > tbScale.Position then
someControl.ScaleBy(100, 105)
else if FtbScalePrevPos < tbScale.Position then
someControl.ScaleBy(105, 100);
FtbScalePrevPos := tbScale.Position;
end;
end;
After scaling above control's dimensions are growing too fast with moving trackbar.
EDIT: My trackbar has Min = 50, Max = 200 and these values are scaling factors in percent. Code for increasing/decreasing tbScale.Position by 5 is a bit complicated but works fine and is not related to origin of my problem. The problem is to find function that will calculate proper scaling factor based on trackbar position. In naive approach with passing tbScale.Position directly to ScaleBy method, if I move trackbar to 150 (scaling factor 1.5) and then to 200 (factor 2), my control will not be scaled by 2 as I would like but by 3 (1.5*2). The simple solution would be to save initial dimensions of someControl and then used them with calculated scaling factor. Unfortunately in my case someControl is TTabSheet and in fact I want to scale its many child controls.
Consider the following changes to your code:
tbScale.Position
in the OnChange
event, use a
local temporary variable instead. Actually, you dont even need the
temporary.tbScale.Tag
tbScale
step = 5 is not necessary, you are only using it
for comparison (<, >
) with previous value.Thus your code is reduced to the following:
procedure TForm22.tbScaleChange(Sender: TObject);
begin
if FtbScalePrevPos > tbScale.Position then
Button1.ScaleBy(100, 105)
else if FtbScalePrevPos < tbScale.Position then
Button1.ScaleBy(105, 100);
FtbScalePrevPos := tbScale.Position;
end;
If incrementing/decrementing with 5% per step goes too fast, reduce 105 to say, 103.
The TTrackBar
has a Min= 0
and Max=10
as default. If you want to be able to reduce the size of the scaled controls, set e.g. Min := -10
. If you want to increase the steps, adjust Min
and Max
.
Edit after additional information.
I now understand what the problem is (I think). In the previous the size change was progressive and you are looking for a linear change.
I still maintain that the calculations you do with the tbScale
value can be replaced with assigning min, max and initial position with a 5th smaller values and multiply with 5 in the OnChange
procedure.
With the range of tbScale2
at 10..40 (instead of 50..200) and initial position at 20 (instead of 100), as well as FtbScale2PrevPos
initialized at 100, the following changes the operation from progressive to linear.
procedure TForm22.FormCreate(Sender: TObject);
begin
FtbScale2PrevPos := 100;
end;
procedure TForm22.tbScale2Change(Sender: TObject);
begin
Button1.ScaleBy(tbScale2.Position * 5, FtbScale2PrevPos);
FtbScale2PrevPos := tbScale2.Position * 5;
end;