Comments (13)
One more thing regarding AutoScale.
In your recent commit the following was added:
if (lTextHeight > Self.DefaultNodeHeight) then begin
ScaleNodeHeights(lTextHeight, DefaultNodeHeight);
Self.DefaultNodeHeight := lTextHeight;
TVTHeaderCracker(FHeader).ChangeScale(lTextHeight, DefaultNodeHeight);
end;// if
It is not a good idea to call TVTHeaderCracker(FHeader).ChangeScale here. This does not just scale the height but also scales the font size and more.
TVTHeader.AutoScale() will be called anyway when the header font changes. So there is no need to separately call it from the VT AutoScale. Instead remove the conditional compilation from:
procedure TVTHeader.FontChanged(Sender : TObject);
begin
inherited;
{$IF CompilerVersion < 31}
AutoScale();
{$IFEND}
end;
and
procedure TVTHeader.StyleChanged();
begin
{$IF CompilerVersion < 31}
AutoScale(False); //Elements may have changed in size
{$IFEND}
end;
Otherwise the header AutoScale would never be called.
Related to this:
procedure TVTHeader.ChangeScale(M, D : TDimension);
var
I : Integer;
begin
//This method is only executed if toAutoChangeScale is set
FMinHeight := MulDiv(FMinHeight, M, D);
FMaxHeight := MulDiv(FMaxHeight, M, D);
Self.Height := MulDiv(FHeight, M, D);
if not ParentFont then
Font.Height := MulDiv(Font.Height, M, D);
//Scale the columns widths too
for I := 0 to FColumns.Count - 1 do
TVirtualTreeColumnCracker(Self.FColumns[I]).ChangeScale(M, D);
end;
Since the change of font will trigger AutoScale which uses the column spacing, the font scaling should happen after the columns are scaled:
procedure TVTHeader.ChangeScale(M, D : TDimension);
var
I : Integer;
begin
//This method is only executed if toAutoChangeScale is set
FMinHeight := MulDiv(FMinHeight, M, D);
FMaxHeight := MulDiv(FMaxHeight, M, D);
Self.Height := MulDiv(FHeight, M, D);
//Scale the columns widths too
for I := 0 to FColumns.Count - 1 do
TVirtualTreeColumnCracker(Self.FColumns[I]).ChangeScale(M, D);
if not ParentFont then
Font.Height := MulDiv(Font.Height, M, D);
end;
Could this be the reason you disabled header AutoScale?
I have tested the above changes and I do not see any negative effects.
from virtual-treeview.
Looking at TControl.Change scale I saw that the FCurrentPPI is updated after the font is changed. So the following would work also when ParentFont is False, since CurrentPPI gets the PPI from the Window handle.
But Shouldn't we then change ChangeScale()
accordingly? And use the property instead of the member?
from virtual-treeview.
ScalePixels will not work when ParentFont is False.
procedure TControl.ChangeScale(M, D: Integer; isDpiChange: Boolean);
var
X, Y, W, H: Integer;
Flags: TScalingFlags;
begin
...
if M <> D then
begin
...
if not ParentFont and (sfFont in Flags) then
Font.Height := MulDiv(Font.Height, M, D);
if [sfLeft, sfWidth] * Flags <> [] then
FOriginalParentSize.X := MulDiv(FOriginalParentSize.X, M, D);
if [sfTop, sfHeight] * Flags <> [] then
FOriginalParentSize.Y := MulDiv(FOriginalParentSize.Y, M, D);
end;
FScalingFlags := [];
if isDpiChange then
FCurrentPPI := M;
end;
When you call inherited ChangeScale, eventually the above method will be called. When ParentFont is False the font is scaled, and the change of the font will trigger AutoScale. But FCurrentPPI, will still be the old FPCurrentPPI. So ScaledPixels will not scale correctly, This is why I suggested that we use:
lTextHeight := Canvas.TextHeight('Tg') + MulDiv(2, CurrentPPI, 96);
instead.
from virtual-treeview.
Sorry, maybe I missed something, this is ScaledPixels()
:
function TBaseVirtualTree.ScaledPixels(pPixels: TDimension): TDimension;
begin
Result := MulDiv(pPixels, {$if CompilerVersion > 31}Self.FCurrentPPI{$else}Screen.PixelsPerInch{$ifend}, 96);
end;
Called with pPixels=2 this makes:
Result := MulDiv(2, FCurrentPPI, 96);
Which is exactly your code, with the difference that the member and not the property is used. Did I get this correct?
If yes, wouldn't it make sense to apply this change to ScaledPixels()
directly?
from virtual-treeview.
Which is exactly your code, with the difference that the member and not the property is used
property CurrentPPI: Integer read GetCurrentPPI;
function TControl.GetCurrentPPI: Integer;
var
LForm: TCustomForm;
Handle: HWnd;
begin
Handle := GetAllocatedWindowHandle;
if not (csDesigning in ComponentState) and (Handle <> 0) and
(TOSVersion.Major >= 10) and (TOSVersion.Build >= 14393) then
begin
LForm := GetParentForm(Self);
if (LForm = nil) or (LForm.Scaled) then
Result := GetDPIforWindow(Handle)
else
Result := FCurrentPPI;
end
else
Result := FCurrentPPI;
end;
In almost all cases ParentForm will not be nil and will Scaled. The result will be GetDPIforWindow(Handle) which does not use FCurrentPPI. CurrentPPI, will return the correct PPI, even before FCurrentPPI is changed.
from virtual-treeview.
So is the core of your suggestion to use the property CurrentPPI
instead of the member FCurrentPPI
?
from virtual-treeview.
So is the core of your suggestion to use the property
CurrentPPI
instead of the memberFCurrentPPI
?
Indeed, in this special case.
from virtual-treeview.
Why do you think the other many call to ScaledPixels()
will work correctly if ParentFont is False?
from virtual-treeview.
Why do you think the other many call to
ScaledPixels()
will work correctly if ParentFont is False?
Yes they will, if they are used outside ChangeScale or inside ChangeScale after the inherited call. In this special case, AutoScale will be called from inside the inherited call, before FCurrentPPI is set.
I am pretty sure the rest of its uses are fine.
Incidentally, this is why CreateSysImageList currently works (see #1204), despite being called before the inherited ChangeScale. Because it uses CurrentPPI instead of FCurrentPPI.
from virtual-treeview.
Also worth noting is, that if ParentFont = True, the font will change after ChangeScale has exited and the font change triggers will work correctly,
from virtual-treeview.
or inside ChangeScale after the inherited call
OK, for now I will move down the call.
from virtual-treeview.
OK, for now I will move down the call.
This will not resolve the issue with using ScaledPixels in AutoScale. When ParentFont is False, AutoScale is called from inside the inherited ChangeScale call.
from virtual-treeview.
Thanks!
I will open a separate issue related to the header AutoScale.
from virtual-treeview.
Related Issues (20)
- Double click on cell reverts focus to VT when custom combobox editor is showed with DroppedDown:=True; HOT 1
- Setting LineStyle to lsDotted does not work HOT 1
- TBaseVirtualTree.AddChild( ) fails for toReadOnly HOT 2
- Clarification please regarding OnFreeNode handling for strings etc HOT 2
- OnShortenString not called for column headers HOT 2
- OnHeaderClick Event triggered twice if vclstyle enabled HOT 2
- Tree lines not painted HOT 3
- How to get lighter/finer GridLines; GridLineColor not used. HOT 4
- Columns EndUpdate and duplicate position HOT 14
- Does TVirtualstringTree support multi-level headers? HOT 1
- AutoScale is setting wrong node height HOT 2
- Packages for Delphi 12 Athens? HOT 1
- Update to Delphi 12 HOT 2
- Access violation while changing the theme HOT 3
- Bad Assert in TVirtualTreeColumns.GetPreviousColumn
- Fixed column MinWidthPercent leads to inifinite loop
- 8.0.1 compile error HOT 3
- Is 7.6.6 an alias of 8.0? HOT 2
- Can't Install VirtualTreesD280.bpl HOT 1
- TVirtualStringTree do not publish `NodeDataSize` HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from virtual-treeview.