diff --git a/components/virtualtreeview/.gitignore b/components/virtualtreeview/.gitignore new file mode 100644 index 00000000..6bf74568 --- /dev/null +++ b/components/virtualtreeview/.gitignore @@ -0,0 +1,45 @@ +# Compiled source # +################### +*.dcu +*.obj +*.exe +*.bpl +*.bpi +*.dcp +*.rsm +*.stat +*.map + +# Generated source # +################### +*.hpp + +# Backup files # +################### +*.~* + +# IDE Files # +################### +*.dproj.local +*.groupproj.local +*.identcache +*.dsk +*.tvsconfig +*.otares +*.drc +*.rc +*.res +*.local + +# Output Folders # +################### +/Win32 +/Win64 +/OSX32 +/__history +*.bak +*.Patch +VirtualTreeView.zip +*.#00 +*.pch +*.skincfg diff --git a/components/virtualtreeview/CHANGES.txt b/components/virtualtreeview/CHANGES.txt index 47d4f770..28830aaa 100644 --- a/components/virtualtreeview/CHANGES.txt +++ b/components/virtualtreeview/CHANGES.txt @@ -1,14 +1,5 @@ -V7.3: (04 Nov 2019) -See: https://github.com/Virtual-TreeView/Virtual-TreeView/milestone/13 - -V7.2.1: (07 Mar 2019) -See: https://github.com/Virtual-TreeView/Virtual-TreeView/milestone/14?closed=1 - -V7.2: (18 Feb 2019) -See: https://github.com/Virtual-TreeView/Virtual-TreeView/milestone/12?closed=1 - -V7.1: (27 Dec 2018) -See: https://github.com/Virtual-TreeView/Virtual-TreeView/milestone/11?closed=1 +V7.1 and later: +https://github.com/JAM-Software/Virtual-TreeView/milestones?state=closed V7.0: (22 Jul 2018) * The support for Windows XP/2003 has been dropped (issue #707). This means: diff --git a/components/virtualtreeview/Delphinus.Info.json b/components/virtualtreeview/Delphinus.Info.json new file mode 100644 index 00000000..5e7439c2 --- /dev/null +++ b/components/virtualtreeview/Delphinus.Info.json @@ -0,0 +1,10 @@ +{ + "id": "{A34BA07B-19B6-4C21-9DEE-65FCA52D00AB}", + "name": "Virtual Treeview", + "picture": "Resources\\VirtualTreeview-Icon.png", + "license_type": "MPL-1.1", + "platforms": "Win32;Win64", + "first_version": "6.2.0", + "package_compiler_min": 24, + "compiler_min": 24 +} \ No newline at end of file diff --git a/components/virtualtreeview/Delphinus.Install.json b/components/virtualtreeview/Delphinus.Install.json new file mode 100644 index 00000000..a193c6c8 --- /dev/null +++ b/components/virtualtreeview/Delphinus.Install.json @@ -0,0 +1,56 @@ +{ + "search_pathes": [ + { + "pathes": "Source", + "platforms": "Win32;Win64" + } + ], + "browsing_pathes": [ + { + "pathes": "Source", + "platforms": "Win32;Win64" + } + ], + "source_folders": [ + { + "folder": "source", + "base": "", + "recursive": true, + "filter": "*;*.*" + }, + { + "folder": "Packages", + "base": "", + "recursive": true, + "filter": "*;*.*" + }, + { + "folder": "Design", + "base": "", + "recursive": true, + "filter": "*;*.*" + } + ], + "projects": [ + { + "project": "Packages\\RAD Studio XE3\\VirtualTreeView.groupproj", + "compiler_max": 26 + }, + { + "project": "Packages\\RAD Studio XE6\\VirtualTreeView.groupproj", + "compiler": 27 + }, + { + "project": "Packages\\RAD Studio XE7\\VirtualTreeView.groupproj", + "compiler": 28 + }, + { + "project": "Packages\\RAD Studio XE8\\VirtualTreeView.groupproj", + "compiler": 29 + }, + { + "project": "Packages\\RAD Studio 10\\VirtualTreeView.groupproj", + "compiler_min": 30 + } + ] +} diff --git a/components/virtualtreeview/INSTALL.txt b/components/virtualtreeview/INSTALL.txt index aaee4dbb..5bebc4c6 100644 --- a/components/virtualtreeview/INSTALL.txt +++ b/components/virtualtreeview/INSTALL.txt @@ -3,9 +3,9 @@ Supported Windows Versions: Windows Vista and higher Extract the entire(!) ZIP file and follow the instructions below. -Delphi / RAD Studio 10.3 and higher Installation +Delphi / RAD Studio 10.4 and higher Installation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -1. Open the project group "Packages\RAD Studio *\VirtualTreeView.groupproj" +1. Open the project group "Packages\RAD Studio 10.4+\VirtualTreeView.groupproj" 2. Right click on "VirtualTreesD*.bpl" and click "Install" 3. Go to "Tools > Options > Language > Delphi Options > Library > Library Path > [...]" Browse to the "Source" folder of VirtualTreeView, press "OK", "Add", "OK" @@ -19,6 +19,22 @@ Delphi / RAD Studio 10.3 and higher Installation 5. Close the RAD Studio Options dialog by clicking "Save". +Delphi / RAD Studio 10.3 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +1. Open the project group "Packages\RAD Studio 10.3\VirtualTreeView.groupproj" +2. Right click on "VirtualTreesD270.bpl" and click "Install" +3. Go to "Tools > Options > Language > Delphi Options > Library > Library Path > [...]" + Browse to the "Source" folder of VirtualTreeView, press "OK", "Add", "OK" + Do this for both Win32 and Win64 platform, which you can choose in the dropdown box. +4. C++ Builder users only: + In the Options dialog go to "Environment Options > C++ Options > Paths and Directories" + a) Click "Library Path > [...]" + Browse to the "Source" folder of VirtualTreeView, press "OK", "Add", "OK" + b) Click "System Include path > [...]" + Browse to the "Source" folder of VirtualTreeView, press "OK", "Add", "OK" +5. Close the RAD Studio Options dialog by clicking "Save". + + Delphi / RAD Studio XE3 - 10.2 Installation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. Open the project group "Packages\RAD Studio *\VirtualTreeView.groupproj" diff --git a/components/virtualtreeview/MAKEFILE b/components/virtualtreeview/MAKEFILE new file mode 100644 index 00000000..e10d0294 --- /dev/null +++ b/components/virtualtreeview/MAKEFILE @@ -0,0 +1,56 @@ +PROJECT = VirtualTrees +EMBARCADERO = $(PROGRAMFILES)\Embarcadero\RAD Studio +STUDIO = $(PROGRAMFILES)\Embarcadero\Studio +BDSCOMMONDIRMAIN = %PUBLIC%\Documents\Embarcadero\Studio +# Default MS Build version +!IF EXIST("$(PROGRAMFILES)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\msbuild.exe") +BUILDEXE = "$(PROGRAMFILES)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\msbuild.exe" +!ELSE +!IF EXIST("$(PROGRAMFILES)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\msbuild.exe") +BUILDEXE = "$(PROGRAMFILES)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\msbuild.exe" +!ELSE +BUILDEXE = "$(PROGRAMFILES)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\msbuild.exe" +!ENDIF +!ENDIF +BUILD = $(BUILDEXE) /t:Rebuild + +clean: + ECHO Project: $(PROJECT) $(EMBARCADERO) + DEL /S /Q .\*.HPP + DEL /S /Q .\*.DCU +#TODO: Add demos and package folders + +# build all packages for Delphi 10.4. Note: The variable $@ is expanded to the build target name +10.1 10.2 10.3 10.4+: Source\*.pas "Packages\RAD Studio $@\$(PROJECT)R.dpk" "Packages\RAD Studio $@\$(PROJECT)R.dproj" "Packages\RAD Studio $@\$(PROJECT)D.dpk" "Packages\RAD Studio $@\$(PROJECT)D.dproj" + SET BDS=$(STUDIO)\21.0 + $(BUILD) "Packages\RAD Studio $@\$(PROJECT)R.dproj" + $(BUILD) "Packages\RAD Studio $@\$(PROJECT)D.dproj" + $(BUILD) /property:Platform=Win64 "Packages\RAD Studio $@\$(PROJECT)R.dproj" + $(MAKE) _samples + +"Demos\Advanced\Advanced.exe": "Demos\Advanced\*.dproj" "Demos\Advanced\*.dpr" "Demos\Advanced\*.pas" + $(BUILD) "Demos\Advanced\Advanced.dproj" + +"Demos\Minimal\Minimal.exe": "Demos\Minimal\*.dproj" "Demos\Minimal\*.dpr" "Demos\Minimal\*.pas" + $(BUILD) "Demos\Minimal\Minimal.dproj" + +"Demos\Objects\Objects.exe": "Demos\Objects\*.dproj" "Demos\Objects\*.dpr" "Demos\Objects\*.pas" + $(BUILD) "Demos\Objects\MVCDemo.dproj" + +"Demos\OLE\OLE.exe": "Demos\OLE\*.dproj" "Demos\OLE\*.dpr" "Demos\OLE\*.pas" + $(BUILD) "Demos\OLE\OLE.dproj" + +_samples: "Demos\Advanced\Advanced.exe" "Demos\Minimal\Minimal.exe" "Demos\Objects\Objects.exe" "Demos\OLE\OLE.exe" + +_continuousbuilds: clean 10.4+ + +_release: +#This small batch file is intended to create a source code release file of the VirtualTreeView as ZIP archive +#It expects the ZIP.EXE from the InfoZip project V3.0 or higher to be in the system's search path +#Download e.g. from: ftp://ftp.info-zip.org/pub/infozip/win32/ + ZIP -9 -r .\VirtualTreeView.zip INSTALL.txt Changes.txt Source Design Packages Demos Contributions Help\VirtualTreeview.chm -i *.pas -i *.dpk -i *.groupproj -i *.dproj -i *.cbproj -i *.hlp -i *.rc -i *.res -i *.cfg -i *.dpr -i *.dof -i *.bpr -i *.dfm -i *.cpp -i *.inc -i *.dcr -i *.chm -i *.png -i *.js -i *.txt -i *.bmp -i *.uni + ECHO Source code zip archive "VirtualTreeView.zip" created. + ECHO !!! Please ensure that the const TVTVersion is correct or remove const!!! + ECHO !!! Please add version number to ZIP file name!!! + ECHO !!! Please create release at: https://github.com/Virtual-TreeView/Virtual-TreeView/releases + ECHO !!! Let JAM web-team upload the file to our server at https://www.jam-software.com/virtual-treeview diff --git a/components/virtualtreeview/MakeRelease.Bat b/components/virtualtreeview/MakeRelease.Bat new file mode 100644 index 00000000..b016c935 --- /dev/null +++ b/components/virtualtreeview/MakeRelease.Bat @@ -0,0 +1,3 @@ +@ECHO OFF +nmake _release +pause \ No newline at end of file diff --git a/components/virtualtreeview/README.md b/components/virtualtreeview/README.md index eec3bb08..b4d981bf 100644 --- a/components/virtualtreeview/README.md +++ b/components/virtualtreeview/README.md @@ -2,10 +2,10 @@ Virtual Treeview is a Delphi treeview control built from ground up. Many years of development made it one of the most flexible and advanced tree controls available today. Virtual Treeview starts off with the claim to improve many aspects of existing solutions and introduces some new technologies and principles which were not available before. ### Help Needed: Any volunteer that takes care about **C++ Builder** bugs and packages? -I don't use C++ Builder and my experience with it is very limited. This makes it difficult to take care about bugs that are reported in C++ Builder and to maintain the C++ Builder packages. I would be great if someone would volunteer to do this. Please contact me at joachim.marder+CPP@gmail.com. +I don't use C++ Builder and my experience with it is very limited. This makes it difficult to take care about bugs that are reported in C++ Builder and to maintain the C++ Builder packages. I would be great if someone would volunteer to do this. ### Downloads -**V7.4** official release for **RAD Studio XE3 to 10.4 Rio**: [JAM Software](https://www.jam-software.com/virtual-treeview/VirtualTreeView.zip) ([Changes](https://github.com/Virtual-TreeView/Virtual-TreeView/milestone/16?closed=1)) +**V7.5** official release for **RAD Studio XE3 to 10.4.2 Rio**: [JAM Software](https://www.jam-software.com/virtual-treeview/VirtualTreeView.zip) ([Changes](https://github.com/JAM-Software/Virtual-TreeView/issues?q=is%3Aissue+milestone%3AV7.5+is%3Aclosed)) An experimental **FireMonkey** port can be found here: [livius2/Virtual-TreeView](https://github.com/livius2/Virtual-TreeView) diff --git a/components/virtualtreeview/Source/VirtualTrees.StyleHooks.pas b/components/virtualtreeview/Source/VirtualTrees.StyleHooks.pas index 89736440..e62b1d3c 100644 --- a/components/virtualtreeview/Source/VirtualTrees.StyleHooks.pas +++ b/components/virtualtreeview/Source/VirtualTrees.StyleHooks.pas @@ -33,8 +33,9 @@ uses Winapi.Windows, Winapi.Messages, Winapi.UxTheme, - System.Classes, + System.UITypes, + Vcl.Graphics, Vcl.Themes, Vcl.Forms, Vcl.Controls; @@ -99,6 +100,9 @@ type public constructor Create(AControl: TWinControl); override; destructor Destroy; override; + /// Draws an expand arrow like used in the RAD Studio IDE. + /// The code is not yet dpi-aware. + class procedure DrawExpandArrow(pBitmap: TBitmap; pExpanded: Boolean; pColor: TColor = clNone); property HorzScrollRect; property VertScrollRect; end; @@ -120,7 +124,6 @@ uses System.SysUtils, System.Math, System.Types, - Vcl.Graphics, VirtualTrees; type @@ -203,6 +206,32 @@ begin inherited; end; +class procedure TVclStyleScrollBarsHook.DrawExpandArrow(pBitmap: TBitmap; pExpanded: Boolean; pColor: TColor); +const + Size: TRect = (Left: 0; Top: 0; Right: 12; Bottom: 12); + ArrowPoints: array[Boolean, 0..5] of TPoint = ( + ((X:3; Y:1), (X:8; Y:6), (X:3; Y:11), (X:4; Y:11), (X:9; Y:6), (X:3; Y:0)), + ((X:1; Y:3), (X:6; Y:8), (X:11; Y:3), (X:11; Y:4), (X:6; Y:9), (X:0; Y:3)) + ); +var + canvas: TCanvas; +begin + pBitmap.SetSize(Size.Width, Size.Height); + canvas := pBitmap.Canvas; + canvas.FillRect(Size); + if pColor = clNone then + begin + if Assigned(VTStyleServicesFunc) then + canvas.Pen.Color := VTStyleServicesFunc.GetSystemColor(clGrayText) + else + canvas.Pen.Color := Vcl.Themes.StyleServices.GetSystemColor(clGrayText) + end + else + canvas.Pen.Color := pColor; + canvas.Pen.Width := 1; + canvas.Polyline(ArrowPoints[pExpanded]); +end; + procedure TVclStyleScrollBarsHook.DrawHorzScrollBar(DC: HDC); var B: TBitmap; diff --git a/components/virtualtreeview/Source/VirtualTrees.Types.pas b/components/virtualtreeview/Source/VirtualTrees.Types.pas new file mode 100644 index 00000000..72e9834f --- /dev/null +++ b/components/virtualtreeview/Source/VirtualTrees.Types.pas @@ -0,0 +1,8 @@ +unit VirtualTrees.Types; +// Dummy unit to make migeration between V7 and V8 easier. + +interface + +implementation + +end. \ No newline at end of file diff --git a/components/virtualtreeview/Source/VirtualTrees.pas b/components/virtualtreeview/Source/VirtualTrees.pas index 7c934517..d6c25789 100644 --- a/components/virtualtreeview/Source/VirtualTrees.pas +++ b/components/virtualtreeview/Source/VirtualTrees.pas @@ -71,13 +71,14 @@ interface {$HPPEMIT '#pragma comment(lib, "VirtualTreesR")'} {$endif} {$HPPEMIT '#pragma comment(lib, "Shell32")'} +{$HPPEMIT '#pragma comment(lib, "uxtheme")'} {$HPPEMIT '#pragma link "VirtualTrees.Accessibility"'} uses Winapi.Windows, Winapi.oleacc, Winapi.Messages, System.SysUtils, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.ImgList, Winapi.ActiveX, Vcl.StdCtrls, System.Classes, Vcl.Menus, Vcl.Printers, System.Types, Winapi.CommCtrl, Vcl.Themes, Winapi.UxTheme, - Winapi.ShlObj, System.UITypes, System.Generics.Collections; + Winapi.ShlObj, System.UITypes, System.Generics.Collections, VirtualTrees.Types; type {$IFDEF VT_FMX} TDimension = Single; @@ -86,7 +87,7 @@ type {$ENDIF} const - VTVersion = '7.5.0' deprecated 'This const is going to be removed in a future version'; + VTVersion = '7.6.0' deprecated 'This const is going to be removed in a future version'; const VTTreeStreamVersion = 3; @@ -639,6 +640,8 @@ type protected // Mitigator function to use the correct style service for this context (either the style assigned to the control for Delphi > 10.4 or the application style) function StyleServices(AControl: TControl = nil): TCustomStyleServices; + //these bypass the side effects in the regular setters. + procedure InternalSetMiscOptions(const Value: TVTMiscOptions); public constructor Create(AOwner: TBaseVirtualTree); virtual; procedure AssignTo(Dest: TPersistent); override; @@ -923,7 +926,8 @@ type procedure HideDragImage; procedure PrepareDrag(DragImage: TBitmap; ImagePosition, HotSpot: TPoint; const DataObject: IDataObject); procedure ShowDragImage; - + property ImagePosition : TPoint read FImagePosition; + property LastPosition : TPoint read FLastPosition; property MoveRestriction: TVTDragMoveRestriction read FRestriction write FRestriction default dmrNone; end; @@ -1044,6 +1048,7 @@ type procedure SetWidth(Value: TDimension); protected FLeft: TDimension; + procedure ChangeScale(M, D: TDimension; isDpiChange: Boolean); virtual; procedure ComputeHeaderLayout(var PaintInfo: THeaderPaintInfo; DrawFormat: Cardinal; CalculateTextRect: Boolean = False); procedure DefineProperties(Filer: TFiler); override; procedure GetAbsoluteBounds(var Left, Right: TDimension); @@ -1051,11 +1056,10 @@ type function GetText: string; virtual; // [IPK] procedure SetText(const Value: string); virtual; // [IPK] private to protected & virtual function GetOwner: TVirtualTreeColumns; reintroduce; + procedure InternalSetWidth(const value : TDimension); //bypass side effects in SetWidth procedure ReadHint(Reader: TReader); procedure ReadText(Reader: TReader); procedure SetCollection(Value: TCollection); override; - property HasImage: Boolean read FHasImage; - property ImageRect: TRect read FImageRect; public constructor Create(Collection: TCollection); override; destructor Destroy; override; @@ -1063,6 +1067,8 @@ type procedure Assign(Source: TPersistent); override; function Equals(OtherColumnObj: TObject): Boolean; override; function GetRect: TRect; virtual; + property HasImage: Boolean read FHasImage; + property ImageRect: TRect read FImageRect; procedure LoadFromStream(const Stream: TStream; Version: Integer); procedure ParentBiDiModeChanged; procedure ParentColorChanged; @@ -1071,9 +1077,11 @@ type procedure SaveToStream(const Stream: TStream); function UseRightToLeftReading: Boolean; + property BonusPixel: Boolean read FBonusPixel write FBonusPixel; property CaptionText: string read FCaptionText; property Left: TDimension read GetLeft; property Owner: TVirtualTreeColumns read GetOwner; + property SpringRest: Single read FSpringRest write FSpringRest; published property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify; property BiDiMode: TBiDiMode read FBiDiMode write SetBiDiMode stored IsBiDiModeStored; @@ -1154,14 +1162,15 @@ type procedure InitializePositionArray; procedure Notify(Item: TCollectionItem; Action: System.Classes.TCollectionNotification); override; procedure ReorderColumns(RTL: Boolean); + procedure SetHoverIndex(index : TColumnIndex); procedure Update(Item: TCollectionItem); override; procedure UpdatePositions(Force: Boolean = False); property HeaderBitmap: TBitmap read FHeaderBitmap; property PositionToIndex: TIndexArray read FPositionToIndex; - property HoverIndex: TColumnIndex read FHoverIndex; - property DownIndex: TColumnIndex read FDownIndex; - property CheckBoxHit: Boolean read FCheckBoxHit; + property HoverIndex: TColumnIndex read FHoverIndex write FHoverIndex; + property DownIndex: TColumnIndex read FDownIndex write FDownIndex; + property CheckBoxHit: Boolean read FCheckBoxHit write FCheckBoxHit; // Mitigator function to use the correct style service for this context (either the style assigned to the control for Delphi > 10.4 or the application style) function StyleServices(AControl: TControl = nil): TCustomStyleServices; public @@ -1198,9 +1207,12 @@ type property Count: Integer read GetCount; property ClickIndex: TColumnIndex read FClickIndex; property DefaultWidth: TDimension read FDefaultWidth write SetDefaultWidth; + property DragIndex : TColumnIndex read FDragIndex write FDragIndex; + property DropBefore : boolean read FDropBefore write FDropBefore; + property DropTarget : TColumnIndex read FDropTarget write FDropTarget; property Items[Index: TColumnIndex]: TVirtualTreeColumn read GetItem write SetItem; default; property Header: TVTHeader read FHeader; - property TrackIndex: TColumnIndex read FTrackIndex; + property TrackIndex: TColumnIndex read FTrackIndex write FTrackIndex; end; TVirtualTreeColumnsClass = class of TVirtualTreeColumns; @@ -2409,7 +2421,6 @@ type function IsLastVisibleChild(Parent, Node: PVirtualNode): Boolean; function MakeNewNode: PVirtualNode; function PackArray({*}const TheArray: TNodeArray; Count: Integer): Integer; - procedure PrepareBitmaps(NeedButtons, NeedLines: Boolean); procedure FakeReadIdent(Reader: TReader); procedure SetAlignment(const Value: TAlignment); procedure SetAnimationDuration(const Value: Cardinal); @@ -2467,7 +2478,6 @@ type procedure PrepareBackGroundPicture(Source: TPicture; DrawBitmap: TBitmap; DrawBitmapWidth: Integer; DrawBitMapHeight: Integer; ABkgcolor: TColor); procedure StaticBackground(Source: TPicture; Target: TCanvas; OffsetPosition: TPoint; R: TRect; aBkgColor: TColor); procedure StopTimer(ID: Integer); - procedure SetWindowTheme(const Theme: string); procedure TileBackground(Source: TPicture; Target: TCanvas; Offset: TPoint; R: TRect; aBkgColor: TColor); function ToggleCallback(Step, StepSize: Integer; Data: Pointer): Boolean; @@ -2548,6 +2558,7 @@ type procedure ChangeTreeStatesAsync(EnterStates, LeaveStates: TVirtualTreeStates); procedure ChangeScale(M, D: Integer{$if CompilerVersion >= 31}; isDpiChange: Boolean{$ifend}); override; function CheckParentCheckState(Node: PVirtualNode; NewCheckState: TCheckState): Boolean; virtual; + procedure ClearDragManager; procedure ClearSelection(pFireChangeEvent: Boolean); overload; virtual; procedure ClearTempCache; virtual; function ColumnIsEmpty(Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual; @@ -2754,6 +2765,7 @@ type procedure PaintSelectionRectangle(Target: TCanvas; WindowOrgX: Integer; const SelectionRect: TRect; TargetRect: TRect); virtual; procedure PanningWindowProc(var Message: TMessage); virtual; + procedure PrepareBitmaps(NeedButtons, NeedLines: Boolean); procedure PrepareCell(var PaintInfo: TVTPaintInfo; WindowOrgX, MaxWidth: Integer); virtual; function ReadChunk(Stream: TStream; Version: Integer; Node: PVirtualNode; ChunkType, ChunkSize: Integer): Boolean; virtual; @@ -2768,6 +2780,8 @@ type procedure SetChildCount(Node: PVirtualNode; NewChildCount: Cardinal); virtual; procedure SetFocusedNodeAndColumn(Node: PVirtualNode; Column: TColumnIndex); virtual; procedure SetRangeX(value: Cardinal); + procedure SetWindowTheme(const Theme: string); + procedure SetVisibleCount(value : Cardinal); procedure SkipNode(Stream: TStream); virtual; procedure StartOperation(OperationKind: TVTOperationKind); procedure StartWheelPanning(Position: TPoint); virtual; @@ -3157,6 +3171,7 @@ type procedure SaveToFile(const FileName: TFileName); procedure SaveToStream(Stream: TStream; Node: PVirtualNode = nil); virtual; function ScaledPixels(pPixels: Integer): Integer; + procedure ScaleNodeHeights(M, D: Integer); function ScrollIntoView(Node: PVirtualNode; Center: Boolean; Horizontally: Boolean = False): Boolean; overload; function ScrollIntoView(Column: TColumnIndex; Center: Boolean; Node: PVirtualNode = nil): Boolean; overload; procedure SelectAll(VisibleOnly: Boolean); @@ -3312,7 +3327,8 @@ type procedure KeyPress(var Key: Char); override; public constructor Create(Link: TStringEditLink); reintroduce; - + procedure ClearLink; + procedure ClearRefLink; procedure Release; virtual; property AutoSelect; @@ -3339,8 +3355,9 @@ type public constructor Create; virtual; destructor Destroy; override; + property Alignment : TAlignment read FAlignment; property Node : PVirtualNode read FNode; // [IPK] Make FNode accessible - property Column: TColumnIndex read FColumn; // [IPK] Make Column(Index) accessible + property Column: TColumnIndex read FColumn; // [IPK] Make Column(Index) accessible function BeginEdit: Boolean; virtual; stdcall; function CancelEdit: Boolean; virtual; stdcall; @@ -3350,6 +3367,8 @@ type function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual; stdcall; procedure ProcessMessage(var Message: TMessage); virtual; stdcall; procedure SetBounds(R: TRect); virtual; stdcall; + property Stopping : boolean read FStopping; + property Tree : TCustomVirtualStringTree read FTree; end; // Describes the type of text to return in the text and draw info retrival events. @@ -4063,7 +4082,7 @@ const // Do not modify the copyright in any way! Usage of this unit is prohibited without the copyright notice // in the compiled binary file. - Copyright: string = 'Virtual Treeview © 1999, 2010, 2016 Mike Lischke, Joachim Marder'; + Copyright: string = 'Virtual Treeview © 1999-2021 Mike Lischke, Joachim Marder'; var StandardOLEFormat: TFormatEtc = ( @@ -4537,6 +4556,13 @@ end; //---------------------------------------------------------------------------------------------------------------------- +procedure TCustomVirtualTreeOptions.InternalSetMiscOptions(const Value: TVTMiscOptions); +begin + FMiscOptions := value; +end; + +//---------------------------------------------------------------------------------------------------------------------- + procedure TCustomVirtualTreeOptions.SetMiscOptions(const Value: TVTMiscOptions); var @@ -4850,7 +4876,7 @@ var begin // Cancel a pending clipboard operation if this data object was created for the clipboard and // is freed because something else is placed there. - if FForClipboard and not (tsClipboardFlushing in FOwner.FStates) then + if FForClipboard and not (tsClipboardFlushing in FOwner.TreeStates) then FOwner.CancelCutOrCopy; // Release any internal clipboard formats @@ -5138,7 +5164,7 @@ begin begin // Note: this format is not used while flushing the clipboard to avoid a dangling reference // when the owner tree is destroyed before the clipboard data is replaced with something else. - if tsClipboardFlushing in FOwner.FStates then + if tsClipboardFlushing in FOwner.TreeStates then Result := E_FAIL else begin @@ -5302,7 +5328,7 @@ destructor TVTDragManager.Destroy; begin // Set the owner's reference to us to nil otherwise it will access an invalid pointer // after our desctruction is complete. - Pointer(FOwner.FDragManager) := nil; + FOwner.ClearDragManager; inherited; end; @@ -6589,16 +6615,16 @@ var UseText: Boolean; R: TRect; begin - AdvancedOwnerDraw := (hoOwnerDraw in Owner.FHeader.FOptions) and Assigned(Owner.FHeader.Treeview.FOnAdvancedHeaderDraw) and Assigned(Owner.FHeader.Treeview.FOnHeaderDrawQueryElements) and - not(csDesigning in Owner.FHeader.Treeview.ComponentState); + AdvancedOwnerDraw := (hoOwnerDraw in Owner.Header.Options) and Assigned(Owner.Header.Treeview.FOnAdvancedHeaderDraw) and Assigned(Owner.Header.Treeview.FOnHeaderDrawQueryElements) and + not(csDesigning in Owner.Header.Treeview.ComponentState); PaintInfo.Column := Self; PaintInfo.TargetCanvas := Owner.FHeaderBitmap.Canvas; with PaintInfo, Column do begin - ShowHeaderGlyph := (hoShowImages in Owner.FHeader.FOptions) and ((Assigned(Owner.FHeader.FImages) and (FImageIndex > -1)) or FCheckBox); - ShowSortGlyph := ((Owner.FHeader.FSortColumn > -1) and (Self = Owner.Items[Owner.FHeader.FSortColumn])) and (hoShowSortGlyphs in Owner.FHeader.FOptions); + ShowHeaderGlyph := (hoShowImages in Owner.Header.Options) and ((Assigned(Owner.Header.Images) and (FImageIndex > -1)) or FCheckBox); + ShowSortGlyph := ((Owner.Header.FSortColumn > -1) and (Self = Owner.Items[Owner.Header.SortColumn])) and (hoShowSortGlyphs in Owner.Header.Options); // This path for text columns or advanced owner draw. // See if the application wants to draw part of the header itself. @@ -6606,7 +6632,7 @@ begin if AdvancedOwnerDraw then begin PaintInfo.Column := Self; - Owner.FHeader.Treeview.DoHeaderDrawQueryElements(PaintInfo, RequestedElements); + Owner.Header.Treeview.DoHeaderDrawQueryElements(PaintInfo, RequestedElements); end; end; @@ -7032,7 +7058,7 @@ var I: TColumnIndex; begin - if not (hsScaling in Owner.FHeader.FStates) then + if not (hsScaling in Owner.Header.States) then if ([coVisible, coFixed] * FOptions = [coVisible, coFixed]) then begin with Owner, FHeader, FFixedAreaConstraints, TreeView do @@ -7040,10 +7066,10 @@ begin TotalFixedMinWidth := 0; TotalFixedMaxWidth := 0; for I := 0 to FColumns.Count - 1 do - if ([coVisible, coFixed] * FColumns[I].FOptions = [coVisible, coFixed]) then + if ([coVisible, coFixed] * FColumns[I].Options = [coVisible, coFixed]) then begin - Inc(TotalFixedMaxWidth, FColumns[I].FMaxWidth); - Inc(TotalFixedMinWidth, FColumns[I].FMinWidth); + Inc(TotalFixedMaxWidth, FColumns[I].MaxWidth); + Inc(TotalFixedMinWidth, FColumns[I].MinWidth); end; // The percentage values have precedence over the pixel values. @@ -7086,6 +7112,14 @@ end; //---------------------------------------------------------------------------------------------------------------------- +procedure TVirtualTreeColumn.ChangeScale(M, D: TDimension; isDpiChange: Boolean); +begin + FMinWidth := MulDiv(FMinWidth, M, D); + FMaxWidth := MulDiv(FMaxWidth, M, D); + FSpacing := MulDiv(FSpacing, M, D); + Self.Width := MulDiv(Self.Width, M, D); +end; + procedure TVirtualTreeColumn.ComputeHeaderLayout(var PaintInfo: THeaderPaintInfo; DrawFormat: Cardinal; CalculateTextRect: Boolean = False); // The layout of a column header is determined by a lot of factors. This method takes them all into account and @@ -7479,6 +7513,13 @@ end; //---------------------------------------------------------------------------------------------------------------------- +procedure TVirtualTreeColumn.InternalSetWidth(const value : TDimension); +begin + FWidth := value; +end; + +//---------------------------------------------------------------------------------------------------------------------- + procedure TVirtualTreeColumn.ReadText(Reader: TReader); begin @@ -7834,7 +7875,7 @@ var begin Result := False; // convert to local coordinates - Inc(P.Y, FHeader.FHeight); + Inc(P.Y, FHeader.Height); NewIndex := ColumnFromPosition(P); if NewIndex <> OldIndex then begin @@ -7890,7 +7931,7 @@ begin // Determine index to be used for auto resizing. This is usually given by the owner's AutoSizeIndex, but // could be different if the column whose resize caused the invokation here is either the auto column itself // or visually to the right of the auto size column. - AutoIndex := FHeader.FAutoSizeIndex; + AutoIndex := FHeader.AutoSizeIndex; if (AutoIndex < 0) or (AutoIndex >= Count) then AutoIndex := Count - 1; @@ -7906,7 +7947,7 @@ begin // Go through all columns and calculate the rest space remaining. for Index := 0 to Count - 1 do - if (Index <> AutoIndex) and (coVisible in Items[Index].FOptions) then + if (Index <> AutoIndex) and (coVisible in Items[Index].Options) then Dec(RestWidth, Items[Index].Width); with Items[AutoIndex] do @@ -7940,15 +7981,15 @@ function TVirtualTreeColumns.AdjustDownColumn(P: TPoint): TColumnIndex; begin // Convert to local coordinates. - Inc(P.Y, FHeader.FHeight); + Inc(P.Y, FHeader.Height); Result := ColumnFromPosition(P); - if (Result > NoColumn) and (Result <> FDownIndex) and (coAllowClick in Items[Result].FOptions) and - (coEnabled in Items[Result].FOptions) then + if (Result > NoColumn) and (Result <> FDownIndex) and (coAllowClick in Items[Result].Options) and + (coEnabled in Items[Result].Options) then begin if FDownIndex > NoColumn then FHeader.Invalidate(Items[FDownIndex]); FDownIndex := Result; - FCheckBoxHit := Items[Result].FHasImage and PtInRect(Items[Result].FImageRect, P) and Items[Result].CheckBox; + FCheckBoxHit := Items[Result].HasImage and PtInRect(Items[Result].ImageRect, P) and Items[Result].CheckBox; FHeader.Invalidate(Items[FDownIndex]); end; end; @@ -7995,7 +8036,7 @@ end; function TVirtualTreeColumns.CanSplitterResize(P: TPoint; Column: TColumnIndex): Boolean; begin - Result := (Column > NoColumn) and ([coResizable, coVisible] * Items[Column].FOptions = [coResizable, coVisible]); + Result := (Column > NoColumn) and ([coResizable, coVisible] * Items[Column].Options = [coResizable, coVisible]); DoCanSplitterResize(P, Column, Result); end; @@ -8035,14 +8076,14 @@ begin Winapi.Windows.DrawTextW(DC, PWideChar(Caption), Length(Caption), Bounds, DrawFormat); end else - begin - OffsetRect(Bounds, 1, 1); - SetTextColor(DC, ColorToRGB(clBtnHighlight)); - Winapi.Windows.DrawTextW(DC, PWideChar(Caption), Length(Caption), Bounds, DrawFormat); - OffsetRect(Bounds, -1, -1); - SetTextColor(DC, ColorToRGB(clBtnShadow)); - Winapi.Windows.DrawTextW(DC, PWideChar(Caption), Length(Caption), Bounds, DrawFormat); - end + begin + OffsetRect(Bounds, 1, 1); + SetTextColor(DC, ColorToRGB(clBtnHighlight)); + Winapi.Windows.DrawTextW(DC, PWideChar(Caption), Length(Caption), Bounds, DrawFormat); + OffsetRect(Bounds, -1, -1); + SetTextColor(DC, ColorToRGB(clBtnShadow)); + Winapi.Windows.DrawTextW(DC, PWideChar(Caption), Length(Caption), Bounds, DrawFormat); + end else begin if Hot then @@ -8139,7 +8180,7 @@ begin if (csDesigning in Header.Treeview.ComponentState) then exit; // Convert vertical position to local coordinates. - Inc(P.Y, FHeader.FHeight); + Inc(P.Y, FHeader.Height); NewClickIndex := ColumnFromPosition(P); with HitInfo do begin @@ -8151,14 +8192,14 @@ begin end; HitInfo.Button := Button; - if (NewClickIndex > NoColumn) and (coAllowClick in Items[NewClickIndex].FOptions) and + if (NewClickIndex > NoColumn) and (coAllowClick in Items[NewClickIndex].Options) and ((NewClickIndex = FDownIndex) or Force) then begin FClickIndex := NewClickIndex; HitInfo.Column := NewClickIndex; HitInfo.HitPosition := [hhiOnColumn]; - if Items[NewClickIndex].FHasImage and PtInRect(Items[NewClickIndex].FImageRect, P) then + if Items[NewClickIndex].HasImage and PtInRect(Items[NewClickIndex].ImageRect, P) then begin Include(HitInfo.HitPosition, hhiOnIcon); if Items[NewClickIndex].CheckBox then @@ -8200,7 +8241,7 @@ begin if (Button = mbRight) then begin - Dec(P.Y, FHeader.FHeight); // popup menus at actual clicked point + Dec(P.Y, FHeader.Height); // popup menus at actual clicked point FreeAndNil(fColumnPopupMenu);// Attention: Do not free the TVTHeaderPopupMenu at the end of this method, otherwise the clikc events of the menu item will not be fired. Self.FDownIndex := NoColumn; Self.FTrackIndex := NoColumn; @@ -8210,7 +8251,7 @@ begin begin Header.Treeview.StopTimer(ScrollTimer); Header.Treeview.StopTimer(HeaderTimer); - Header.FColumns.FHoverIndex := NoColumn; + Header.Columns.SetHoverIndex(NoColumn); Header.Treeview.DoStateChange([], [tsScrollPending, tsScrolling]); Menu.PopupComponent := Header.Treeview; @@ -8356,9 +8397,9 @@ procedure TVirtualTreeColumns.Notify(Item: TCollectionItem; Action: System.Class var I: Integer; begin - if Action in [cnExtracting, cnDeleting] then + if Action in [cnDeleting] then begin - // Adjust all positions larger than the deleted column's position. Fixes #959 + // Adjust all positions larger than the deleted column's position. Fixes #959, #1049 for I := 0 to Count - 1 do begin if Items[I].Position > TVirtualTreeColumn(Item).Position then Items[I].Position := Items[I].Position - 1; @@ -8394,6 +8435,13 @@ end; //---------------------------------------------------------------------------------------------------------------------- +procedure TVirtualTreeColumns.SetHoverIndex(index : TColumnIndex); +begin + FHoverIndex := index; +end; + +//---------------------------------------------------------------------------------------------------------------------- + procedure TVirtualTreeColumns.EndUpdate; begin InitializePositionArray(); @@ -8416,9 +8464,9 @@ begin // The first column which is created is by definition also the main column. if (Count > 0) and (Header.FMainColumn < 0) then - FHeader.FMainColumn := 0; + FHeader.MainColumn := 0; - if not (csLoading in Header.Treeview.ComponentState) and not (hsLoading in FHeader.FStates) then + if not (csLoading in FHeader.Treeview.ComponentState) and not (hsLoading in FHeader.States) then begin with FHeader do begin @@ -8502,10 +8550,10 @@ begin Exit; // Just in case. // Make sure the width constrains are considered. - if NewWidth < Items[Column].FMinWidth then - NewWidth := Items[Column].FMinWidth; - if NewWidth > Items[Column].FMaxWidth then - NewWidth := Items[Column].FMaxWidth; + if NewWidth < Items[Column].MinWidth then + NewWidth := Items[Column].MinWidth; + if NewWidth > Items[Column].MaxWidth then + NewWidth := Items[Column].MaxWidth; OldWidth := Items[Column].Width; // Nothing to do if the width is the same. @@ -8645,7 +8693,7 @@ begin Inc(Sum, ComputeRTLOffset(True)); for I := 0 to Count - 1 do - if coVisible in Items[FPositionToIndex[I]].FOptions then + if coVisible in Items[FPositionToIndex[I]].Options then begin Inc(Sum, Items[FPositionToIndex[I]].Width); if P.X < Sum then @@ -8780,9 +8828,9 @@ begin if (UpdateCount > 0) or (csLoading in Header.TreeView.ComponentState) then exit; // See issue #760 for I := 0 to Count - 1 do - if (coVisible in Items[FPositionToIndex[I]].FOptions) and + if (coVisible in Items[FPositionToIndex[I]].Options) and ( (not ConsiderAllowFocus) or - (coAllowFocus in Items[FPositionToIndex[I]].FOptions) + (coAllowFocus in Items[FPositionToIndex[I]].Options) ) then begin Result := FPositionToIndex[I]; @@ -8806,9 +8854,9 @@ begin if (UpdateCount > 0) or (csLoading in Header.TreeView.ComponentState) then exit; // See issue #760 for I := Count - 1 downto 0 do - if (coVisible in Items[FPositionToIndex[I]].FOptions) and + if (coVisible in Items[FPositionToIndex[I]].Options) and ( (not ConsiderAllowFocus) or - (coAllowFocus in Items[FPositionToIndex[I]].FOptions) + (coAllowFocus in Items[FPositionToIndex[I]].Options) ) then begin Result := FPositionToIndex[I]; @@ -8863,9 +8911,9 @@ begin repeat Result := GetNextColumn(Result); until (Result = InvalidColumn) or - ( (coVisible in Items[Result].FOptions) and + ( (coVisible in Items[Result].Options) and ( (not ConsiderAllowFocus) or - (coAllowFocus in Items[Result].FOptions) + (coAllowFocus in Items[Result].Options) ) ); end; @@ -8904,9 +8952,9 @@ begin repeat Result := GetPreviousColumn(Result); until (Result = InvalidColumn) or - ( (coVisible in Items[Result].FOptions) and + ( (coVisible in Items[Result].Options) and ( (not ConsiderAllowFocus) or - (coAllowFocus in Items[Result].FOptions) + (coAllowFocus in Items[Result].Options) ) ); end; @@ -8925,7 +8973,7 @@ begin Counter := 0; for I := 0 to Count - 1 do - if coVisible in Items[FPositionToIndex[I]].FOptions then + if coVisible in Items[FPositionToIndex[I]].Options then begin Result[Counter] := Items[FPositionToIndex[I]]; Inc(Counter); @@ -9129,7 +9177,7 @@ var end else begin - if (FHeader.Treeview.VclStyleEnabled and (seClient in FHeader.FOwner.StyleElements)) then + if (FHeader.Treeview.VclStyleEnabled and (seClient in FHeader.Treeview.StyleElements)) then begin Details := StyleServices.GetElementDetails(thHeaderItemRightNormal); StyleServices.DrawElement(Handle, Details, BackgroundRect, @BackgroundRect {$IF CompilerVersion >= 34}, FHeader.Treeview.FCurrentPPI{$IFEND}); @@ -9143,7 +9191,7 @@ var end else begin - Brush.Color := FHeader.FBackgroundColor; + Brush.Color := FHeader.Background; FillRect(BackgroundRect); end; end; @@ -9175,7 +9223,7 @@ var PaintInfo.Column := Items[AColumn]; with PaintInfo, Column do begin - IsHoverIndex := (AColumn = FHoverIndex) and (hoHotTrack in FHeader.FOptions) and (coEnabled in FOptions); + IsHoverIndex := (AColumn = FHoverIndex) and (hoHotTrack in FHeader.Options) and (coEnabled in FOptions); IsDownIndex := (AColumn = FDownIndex) and not FCheckBoxHit; if (coShowDropMark in FOptions) and (AColumn = FDropTarget) and (AColumn <> FDragIndex) then @@ -9202,8 +9250,8 @@ var DropMark := dmmNone; IsEnabled := (coEnabled in FOptions) and (FHeader.Treeview.Enabled); - ShowHeaderGlyph := (hoShowImages in FHeader.FOptions) and ((Assigned(Images) and (FImageIndex > -1)) or FCheckBox); - ShowSortGlyph := (AColumn = FHeader.FSortColumn) and (hoShowSortGlyphs in FHeader.FOptions); + ShowHeaderGlyph := (hoShowImages in FHeader.Options) and ((Assigned(Images) and (FImageIndex > -1)) or FCheckBox); + ShowSortGlyph := (AColumn = FHeader.SortColumn) and (hoShowSortGlyphs in FHeader.Options); WrapCaption := coWrapCaption in FOptions; PaintRectangle := ATargetRect; @@ -9228,7 +9276,7 @@ var FHeader.Treeview.DoAdvancedHeaderDraw(PaintInfo, [hpeBackground]) else begin - if FHeader.Treeview.VclStyleEnabled and (seClient in FHeader.FOwner.StyleElements) then + if FHeader.Treeview.VclStyleEnabled and (seClient in FHeader.Treeview.StyleElements) then begin if IsDownIndex then Details := StyleServices.GetElementDetails(thHeaderItemPressed) @@ -9342,7 +9390,7 @@ var if IsHoverIndex and FHeader.Treeview.VclStyleEnabled then DrawHot := True else - DrawHot := (IsHoverIndex and (hoHotTrack in FHeader.FOptions) and not(tsUseThemes in FHeader.Treeview.FStates)); + DrawHot := (IsHoverIndex and (hoHotTrack in FHeader.Options) and not(tsUseThemes in FHeader.Treeview.FStates)); if not(hpeText in ActualElements) and (Length(Text) > 0) then DrawButtonText(TargetCanvas.Handle, ColCaptionText, TextRectangle, IsEnabled, DrawHot, DrawFormat, WrapCaption); @@ -9354,17 +9402,17 @@ var Pos.TopLeft := SortGlyphPos; Pos.Right := Pos.Left + SortGlyphSize.cx; Pos.Bottom := Pos.Top + SortGlyphSize.cy; - if FHeader.FSortDirection = sdAscending then + if FHeader.SortDirection = sdAscending then Glyph := thHeaderSortArrowSortedUp else Glyph := thHeaderSortArrowSortedDown; Details := StyleServices.GetElementDetails(Glyph); if not StyleServices.DrawElement(TargetCanvas.Handle, Details, Pos, @Pos {$IF CompilerVersion >= 34}, FHeader.TreeView.FCurrentPPI {$IFEND}) then - PaintInfo.DrawSortArrow(FHeader.FSortDirection); + PaintInfo.DrawSortArrow(FHeader.SortDirection); end else begin - PaintInfo.DrawSortArrow(FHeader.FSortDirection); + PaintInfo.DrawSortArrow(FHeader.SortDirection); end; end; @@ -9398,9 +9446,9 @@ begin Exit; // If both draw posibillities are specified then prefer the advanced way. - AdvancedOwnerDraw := (hoOwnerDraw in FHeader.FOptions) and Assigned(FHeader.Treeview.FOnAdvancedHeaderDraw) and + AdvancedOwnerDraw := (hoOwnerDraw in FHeader.Options) and Assigned(FHeader.Treeview.OnAdvancedHeaderDraw) and Assigned(FHeader.Treeview.FOnHeaderDrawQueryElements) and not (csDesigning in FHeader.Treeview.ComponentState); - OwnerDraw := (hoOwnerDraw in FHeader.FOptions) and Assigned(FHeader.Treeview.FOnHeaderDraw) and + OwnerDraw := (hoOwnerDraw in FHeader.Options) and Assigned(FHeader.Treeview.OnHeaderDraw) and not (csDesigning in FHeader.Treeview.ComponentState) and not AdvancedOwnerDraw; ZeroMemory(@PaintInfo, SizeOf(PaintInfo)); @@ -9409,8 +9457,8 @@ begin with PaintInfo, TargetCanvas do begin // Use shortcuts for the images and the font. - Images := FHeader.FImages; - Font := FHeader.FFont; + Images := FHeader.Images; + Font := FHeader.Font; PrepareButtonStyles; @@ -9444,13 +9492,13 @@ begin TargetRect.Left := Target.X - R.Left + Items[Run].FLeft + RTLOffset; // TargetRect.Right will be set in the loop - ShowRightBorder := (FHeader.Style = hsThickButtons) or not (hoAutoResize in FHeader.FOptions) or + ShowRightBorder := (FHeader.Style = hsThickButtons) or not (hoAutoResize in FHeader.Options) or (FHeader.Treeview.BevelKind = bkNone); // Now go for each button. while (Run > NoColumn) and (TargetRect.Left < MaxX) do begin - TargetRect.Right := TargetRect.Left + Items[Run].FWidth; + TargetRect.Right := TargetRect.Left + Items[Run].Width; // create a clipping rect to limit painting to button area ClipCanvas(TargetCanvas, Rect(Max(TargetRect.Left, Target.X), Target.Y + R.Top, @@ -9500,7 +9548,7 @@ begin if (Count > 0) and (Length(FPositionToIndex) > 0) then begin LastColumn := FPositionToIndex[Count - 1]; - if not (coVisible in Items[LastColumn].FOptions) then + if not (coVisible in Items[LastColumn].Options) then LastColumn := GetPreviousVisibleColumn(LastColumn); if LastColumn > NoColumn then with Items[LastColumn] do @@ -9644,7 +9692,9 @@ end; procedure TVTHeader.FontChanged(Sender: TObject); begin inherited; - AutoScale(); + {$IF CompilerVersion < 31} // See issue #1043 + AutoScale(); + {$IFEND} end; procedure TVTHeader.AutoScale(); @@ -9843,7 +9893,7 @@ begin if not (csLoading in Treeview.ComponentState) then begin Treeview.MainColumnChanged; - if not (toExtendedFocus in Treeview.FOptions.FSelectionOptions) then + if not (toExtendedFocus in Treeview.TreeOptions.SelectionOptions) then Treeview.FocusedColumn := FMainColumn; Treeview.Invalidate; end; @@ -9941,7 +9991,7 @@ begin begin FSortDirection := Value; Invalidate(nil); - if ((toAutoSort in Treeview.FOptions.FAutoOptions) or (hoHeaderClickAutoSort in Options)) and (Treeview.FUpdateCount = 0) then + if ((toAutoSort in Treeview.TreeOptions.AutoOptions) or (hoHeaderClickAutoSort in Options)) and (Treeview.UpdateCount = 0) then Treeview.SortTree(FSortColumn, FSortDirection, True); end; end; @@ -9970,7 +10020,9 @@ end; procedure TVTHeader.StyleChanged(); begin - AutoScale(); // Elements may have chnaged in size + {$IF CompilerVersion < 31} // See issue #1043 + AutoScale(False); //Elements may have changed in size + {$IFEND} end; //---------------------------------------------------------------------------------------------------------------------- @@ -9997,9 +10049,7 @@ begin Font.Height := MulDiv(Font.Height, M, D); // Scale the columns widths too for I := 0 to FColumns.Count - 1 do - begin - Self.FColumns[I].Width := MulDiv(Self.FColumns[I].Width, M, D); - end;//for I + Self.FColumns[I].ChangeScale(M, D, isDpiChange); if not isDpiChange then AutoScale(); end; @@ -10039,7 +10089,7 @@ begin if FColumns.Count > 0 then begin - FColumns.FTrackIndex := NoColumn; + FColumns.TrackIndex := NoColumn; VisibleFixedWidth := FColumns.GetVisibleFixedWidth; LeftTolerance := Round(SplitterHitTolerance * 0.6); if Treeview.UseRightToLeftAlignment then @@ -10244,7 +10294,7 @@ begin FSortDirection := pSortDirection; if FSortColumn > NoColumn then Invalidate(Columns[FSortColumn]); - if ((toAutoSort in Treeview.FOptions.FAutoOptions) or (hoHeaderClickAutoSort in Options)) and (Treeview.FUpdateCount = 0) then + if ((toAutoSort in Treeview.TreeOptions.AutoOptions) or (hoHeaderClickAutoSort in Options)) and (Treeview.UpdateCount = 0) then Treeview.SortTree(FSortColumn, FSortDirection, True); end; end; @@ -10271,30 +10321,30 @@ begin // Make coordinates relative to (0, 0) of the non-client area. Inc(ClientP.Y, FHeight); NewTarget := FColumns.ColumnFromPosition(ClientP); - NeedRepaint := (NewTarget <> InvalidColumn) and (NewTarget <> FColumns.FDropTarget); + NeedRepaint := (NewTarget <> InvalidColumn) and (NewTarget <> FColumns.DropTarget); if NewTarget >= 0 then begin FColumns.GetColumnBounds(NewTarget, Left, Right); - if (ClientP.X < ((Left + Right) div 2)) <> FColumns.FDropBefore then + if (ClientP.X < ((Left + Right) div 2)) <> FColumns.DropBefore then begin NeedRepaint := True; - FColumns.FDropBefore := not FColumns.FDropBefore; + FColumns.DropBefore := not FColumns.DropBefore; end; end; if NeedRepaint then begin // Invalidate columns which need a repaint. - if FColumns.FDropTarget > NoColumn then + if FColumns.DropTarget > NoColumn then begin - I := FColumns.FDropTarget; - FColumns.FDropTarget := NoColumn; + I := FColumns.DropTarget; + FColumns.DropTarget := NoColumn; Invalidate(FColumns.Items[I]); end; - if (NewTarget > NoColumn) and (NewTarget <> FColumns.FDropTarget) then + if (NewTarget > NoColumn) and (NewTarget <> FColumns.DropTarget) then begin Invalidate(FColumns.Items[NewTarget]); - FColumns.FDropTarget := NewTarget; + FColumns.DropTarget := NewTarget; end; end; @@ -10309,8 +10359,8 @@ begin // drag image is over the header. if // determine the case when the drag image is or was on the header area - (InHeader(FOwner.ScreenToClient(FDragImage.FLastPosition)) - or InHeader(FOwner.ScreenToClient(FDragImage.FImagePosition)) + (InHeader(FOwner.ScreenToClient(FDragImage.LastPosition)) + or InHeader(FOwner.ScreenToClient(FDragImage.ImagePosition)) ) then begin GDIFlush; @@ -10411,29 +10461,29 @@ begin else if hsColumnWidthTracking in FStates then begin - if DoColumnWidthTracking(FColumns.FTrackIndex, GetShiftState, FTrackPoint, P) then + if DoColumnWidthTracking(FColumns.TrackIndex, GetShiftState, FTrackPoint, P) then begin if Treeview.UseRightToLeftAlignment then begin NewWidth := FTrackPoint.X - XPos; - NextColumn := FColumns.GetPreviousVisibleColumn(FColumns.FTrackIndex); + NextColumn := FColumns.GetPreviousVisibleColumn(FColumns.TrackIndex); end else begin NewWidth := XPos - FTrackPoint.X; - NextColumn := FColumns.GetNextVisibleColumn(FColumns.FTrackIndex); + NextColumn := FColumns.GetNextVisibleColumn(FColumns.TrackIndex); end; // The autosized column cannot be resized using the mouse normally. Instead we resize the next // visible column, so it look as we directly resize the autosized column. - if (hoAutoResize in FOptions) and (FColumns.FTrackIndex = FAutoSizeIndex) and - (NextColumn > NoColumn) and (coResizable in FColumns[NextColumn].FOptions) and - (FColumns[FColumns.FTrackIndex].FMinWidth < NewWidth) and - (FColumns[FColumns.FTrackIndex].FMaxWidth > NewWidth) then + if (hoAutoResize in FOptions) and (FColumns.TrackIndex = FAutoSizeIndex) and + (NextColumn > NoColumn) and (coResizable in FColumns[NextColumn].Options) and + (FColumns[FColumns.TrackIndex].MinWidth < NewWidth) and + (FColumns[FColumns.TrackIndex].MaxWidth > NewWidth) then FColumns[NextColumn].Width := FColumns[NextColumn].Width - NewWidth - + FColumns[FColumns.FTrackIndex].Width + + FColumns[FColumns.TrackIndex].Width else - FColumns[FColumns.FTrackIndex].Width := NewWidth; // 1 EListError seen here (List index out of bounds (-1)) since 10/2013 + FColumns[FColumns.TrackIndex].Width := NewWidth; // 1 EListError seen here (List index out of bounds (-1)) since 10/2013 end; HandleHeaderMouseMove := True; Result := 0; @@ -10452,15 +10502,15 @@ begin begin P := Treeview.ClientToScreen(P); // start actual dragging if allowed - if (hoDrag in FOptions) and Treeview.DoHeaderDragging(FColumns.FDownIndex) then + if (hoDrag in FOptions) and Treeview.DoHeaderDragging(FColumns.DownIndex) then begin if ((Abs(FDragStart.X - P.X) > Mouse.DragThreshold) or (Abs(FDragStart.Y - P.Y) > Mouse.DragThreshold)) then begin Treeview.StopTimer(HeaderTimer); - I := FColumns.FDownIndex; - FColumns.FDownIndex := NoColumn; - FColumns.FHoverIndex := NoColumn; + I := FColumns.DownIndex; + FColumns.DownIndex := NoColumn; + FColumns.HoverIndex := NoColumn; if I > NoColumn then Invalidate(FColumns[I]); PrepareDrag(P, FDragStart); @@ -10514,8 +10564,8 @@ var Result := (hoColumnResize in FOptions) and DetermineSplitterIndex(P); if Result and not InHeader(P) then begin - NextCol := FColumns.GetNextVisibleColumn(FColumns.FTrackIndex); - if not (coFixed in FColumns[FColumns.FTrackIndex].Options) or (NextCol <= NoColumn) or + NextCol := FColumns.GetNextVisibleColumn(FColumns.TrackIndex); + if not (coFixed in FColumns[FColumns.TrackIndex].Options) or (NextCol <= NoColumn) or (coFixed in FColumns[NextCol].Options) or (P.Y > Integer(Treeview.FRangeY)) then Result := False; end; @@ -10528,7 +10578,7 @@ begin case Message.Msg of WM_SIZE: begin - if not (tsWindowCreating in FOwner.FStates) then + if not (tsWindowCreating in FOwner.TreeStates) then if (hoAutoResize in FOptions) and not (hsAutoSizing in FStates) then begin FColumns.AdjustAutoSize(InvalidColumn); @@ -10546,7 +10596,7 @@ begin FFont.Assign(FOwner.Font); CM_BIDIMODECHANGED: for I := 0 to FColumns.Count - 1 do - if coParentBiDiMode in FColumns[I].FOptions then + if coParentBiDiMode in FColumns[I].Options then FColumns[I].ParentBiDiModeChanged; WM_NCMBUTTONDOWN: begin @@ -10563,8 +10613,8 @@ begin begin FColumns.HandleClick(P, mbMiddle, True, False); FOwner.DoHeaderMouseUp(mbMiddle, GetShiftState, P.X, P.Y + Integer(FHeight)); - FColumns.FDownIndex := NoColumn; - FColumns.FCheckBoxHit := False; + FColumns.DownIndex := NoColumn; + FColumns.CheckBoxHit := False; end; end; WM_LBUTTONDBLCLK, @@ -10587,12 +10637,12 @@ begin end else if HSplitterHit and ((Message.Msg = WM_NCLBUTTONDBLCLK) or (Message.Msg = WM_LBUTTONDBLCLK)) and - (hoDblClickResize in FOptions) and (FColumns.FTrackIndex > NoColumn) then + (hoDblClickResize in FOptions) and (FColumns.TrackIndex > NoColumn) then begin // If the click was on a splitter then resize column to smallest width. - if DoColumnWidthDblClickResize(FColumns.FTrackIndex, P, GetShiftState) then - AutoFitColumns(True, smaUseColumnOption, FColumns[FColumns.FTrackIndex].FPosition, - FColumns[FColumns.FTrackIndex].FPosition); + if DoColumnWidthDblClickResize(FColumns.TrackIndex, P, GetShiftState) then + AutoFitColumns(True, smaUseColumnOption, FColumns[FColumns.TrackIndex].Position, + FColumns[FColumns.TrackIndex].Position); Message.Result := 0; Result := True; end @@ -10658,7 +10708,7 @@ begin if IsVSplitterHit or IsHSplitterHit then begin FTrackStart := P; - FColumns.FHoverIndex := NoColumn; + FColumns.HoverIndex := NoColumn; if IsVSplitterHit then begin if not (csDesigning in Treeview.ComponentState) then @@ -10668,7 +10718,7 @@ begin else begin if not (csDesigning in Treeview.ComponentState) then - DoBeforeColumnWidthTracking(FColumns.FTrackIndex, GetShiftState); + DoBeforeColumnWidthTracking(FColumns.TrackIndex, GetShiftState); Include(FStates, hsColumnWidthTrackPending); end; @@ -10682,7 +10732,7 @@ begin HitIndex := Columns.AdjustDownColumn(P); // in design-time header columns are always draggable if ((csDesigning in Treeview.ComponentState) and (HitIndex > NoColumn)) or - ((hoDrag in FOptions) and (HitIndex > NoColumn) and (coDraggable in FColumns[HitIndex].FOptions)) then + ((hoDrag in FOptions) and (HitIndex > NoColumn) and (coDraggable in FColumns[HitIndex].Options)) then begin // Show potential drag operation. // Disabled columns do not start a drag operation because they can't be clicked. @@ -10757,7 +10807,7 @@ begin if (FDropTarget > -1) and (FDropTarget <> FDragIndex) and PtInRect(R, P) then begin OldPosition := FColumns[FDragIndex].Position; - if FColumns.FDropBefore then + if FColumns.DropBefore then begin if FColumns[FDragIndex].Position < FColumns[FDropTarget].Position then FColumns[FDragIndex].Position := Max(0, FColumns[FDropTarget].Position - 1) @@ -10787,7 +10837,7 @@ begin WM_LBUTTONUP: with TWMLButtonUp(Message) do begin - if FColumns.FDownIndex > NoColumn then + if FColumns.DownIndex > NoColumn then FColumns.HandleClick(Point(XPos, YPos), mbLeft, False, False); if FStates <> [] then FOwner.DoHeaderMouseUp(mbLeft, KeysToShiftState(Keys), XPos, YPos); @@ -10801,17 +10851,17 @@ begin end; end; - if FColumns.FTrackIndex > NoColumn then + if FColumns.TrackIndex > NoColumn then begin if hsColumnWidthTracking in FStates then - DoAfterColumnWidthTracking(FColumns.FTrackIndex); - Invalidate(Columns[FColumns.FTrackIndex]); - FColumns.FTrackIndex := NoColumn; + DoAfterColumnWidthTracking(FColumns.TrackIndex); + Invalidate(Columns[FColumns.TrackIndex]); + FColumns.TrackIndex := NoColumn; end; - if FColumns.FDownIndex > NoColumn then + if FColumns.DownIndex > NoColumn then begin - Invalidate(Columns[FColumns.FDownIndex]); - FColumns.FDownIndex := NoColumn; + Invalidate(Columns[FColumns.DownIndex]); + FColumns.DownIndex := NoColumn; end; if hsHeightTracking in FStates then DoAfterHeightTracking; @@ -10916,7 +10966,7 @@ begin ReleaseCapture; FDragImage.EndDrag; Exclude(FStates, hsDragging); - FColumns.FDropTarget := NoColumn; + FColumns.DropTarget := NoColumn; Invalidate(nil); Result := True; Message.Result := 0; @@ -10927,7 +10977,7 @@ begin begin ReleaseCapture; if hsColumnWidthTracking in FStates then - DoAfterColumnWidthTracking(FColumns.FTrackIndex); + DoAfterColumnWidthTracking(FColumns.TrackIndex); if hsHeightTracking in FStates then DoAfterHeightTracking; Result := True; @@ -10964,11 +11014,11 @@ var begin // Determine initial position of drag image (screen coordinates). - FColumns.FDropTarget := NoColumn; + FColumns.DropTarget := NoColumn; Start := Treeview.ScreenToClient(Start); Inc(Start.Y, FHeight); - FColumns.FDragIndex := FColumns.ColumnFromPosition(Start); - DragColumn := FColumns[FColumns.FDragIndex]; + FColumns.DragIndex := FColumns.ColumnFromPosition(Start); + DragColumn := FColumns[FColumns.DragIndex]; Image := TBitmap.Create; with Image do @@ -11058,7 +11108,7 @@ var while I > NoColumn do begin if (coFixed in FColumns[I].Options) and (FColumns[I].Width < FColumns[I].MinWidth) then - FColumns[I].FWidth := FColumns[I].FMinWidth; + FColumns[I].InternalSetWidth(FColumns[I].MinWidth); //SetWidth has side effects and this bypasses them I := GetNextVisibleColumn(I); end; FixedWidth := GetVisibleFixedWidth; @@ -11146,7 +11196,7 @@ begin // Count how many columns have spring enabled. SpringCount := 0; for I := 0 to FColumns.Count-1 do - if [coVisible, coAutoSpring] * FColumns[I].FOptions = [coVisible, coAutoSpring] then + if [coVisible, coAutoSpring] * FColumns[I].Options = [coVisible, coAutoSpring] then Inc(SpringCount); if SpringCount > 0 then begin @@ -11154,15 +11204,15 @@ begin Difference := ChangeBy / SpringCount; // Adjust the column's size accumulators and resize if the result is >= 1. for I := 0 to FColumns.Count - 1 do - if [coVisible, coAutoSpring] * FColumns[I].FOptions = [coVisible, coAutoSpring] then + if [coVisible, coAutoSpring] * FColumns[I].Options = [coVisible, coAutoSpring] then begin // Sum up rest changes from previous runs and the amount from this one and store it in the // column. If there is at least one pixel difference then do a resize and reset the accumulator. - NewAccumulator := FColumns[I].FSpringRest + Difference; + NewAccumulator := FColumns[I].SpringRest + Difference; // Set new width if at least one pixel size difference is reached. if NewAccumulator >= 1 then - FColumns[I].SetWidth(FColumns[I].FWidth + (Trunc(NewAccumulator) * Sign)); - FColumns[I].FSpringRest := Frac(NewAccumulator); + FColumns[I].SetWidth(FColumns[I].Width + (Trunc(NewAccumulator) * Sign)); + FColumns[I].SpringRest := Frac(NewAccumulator); // Keep track of the size count. ChangeBy := ChangeBy - Difference; @@ -11269,7 +11319,7 @@ procedure TVTHeader.AutoFitColumns(Animated: Boolean = True; SmartAutoFitType: T smaAllColumns: Result := True; smaUseColumnOption: - Result := coSmartResize in FColumns.Items[ColumnIndex].FOptions; + Result := coSmartResize in FColumns.Items[ColumnIndex].Options; else Result := False; end; @@ -11281,7 +11331,7 @@ procedure TVTHeader.AutoFitColumns(Animated: Boolean = True; SmartAutoFitType: T begin with FColumns do - if ([coResizable, coVisible] * Items[FPositionToIndex[Column]].FOptions = [coResizable, coVisible]) and + if ([coResizable, coVisible] * Items[FPositionToIndex[Column]].Options = [coResizable, coVisible]) and DoBeforeAutoFitColumn(FPositionToIndex[Column], SmartAutoFitType) and not TreeView.OperationCanceled then begin if Animated then @@ -11413,7 +11463,7 @@ begin OffsetRect(R, ComputeRTLOffset, 0); if ExpandToBorder then begin - if (hoFullRepaintOnResize in FHeader.FOptions) then + if (hoFullRepaintOnResize in FHeader.Options) then begin R.Left := FHeaderRect.Left; R.Right := FHeaderRect.Right; @@ -11621,8 +11671,8 @@ var MaxWidth := 0; MaxReserveCol := NoColumn; for Column := RangeStartCol to RangeEndCol do - if (Options * FColumns[Column].FOptions = Options) and - (FColumns[Column].FWidth > MaxWidth) then + if (Options * FColumns[Column].Options = Options) and + (FColumns[Column].Width > MaxWidth) then begin MaxWidth := Widths[Column - RangeStartCol]; MaxReserveCol := Column; @@ -11639,7 +11689,7 @@ var begin Result := 0; - if ChangeBy <> 0 then + if (ChangeBy <> 0) and (RangeEndCol >= 0) then // RangeEndCol == -1 means no columns, so nothing to do begin // Do some initialization here BonusPixel := ChangeBy > 0; @@ -11650,7 +11700,7 @@ begin SetLength(Constraints, RangeEndCol - RangeStartCol + 1); for I := RangeStartCol to RangeEndCol do begin - Widths[I - RangeStartCol] := FColumns[I].FWidth; + Widths[I - RangeStartCol] := FColumns[I].Width; Constraints[I - RangeStartCol] := IfThen(BonusPixel, FColumns[I].MaxWidth, FColumns[I].MinWidth); end; @@ -11659,7 +11709,7 @@ begin MaxDelta := 0; ColCount := 0; for I := RangeStartCol to RangeEndCol do - if (Options * FColumns[I].FOptions = Options) and IsResizable(I) then + if (Options * FColumns[I].Options = Options) and IsResizable(I) then begin Inc(ColCount); IncDelta(I); @@ -11678,25 +11728,25 @@ begin if Difference > 0 then for I := RangeStartCol to RangeEndCol do - if (Options * FColumns[I].FOptions = Options) and IsResizable(I) then + if (Options * FColumns[I].Options = Options) and IsResizable(I) then ChangeWidth(I, Difference * Sign); // Now distribute Rest. I := Start; while Rest > 0 do begin - if (Options * FColumns[I].FOptions = Options) and IsResizable(I) then - if FColumns[I].FBonusPixel <> BonusPixel then + if (Options * FColumns[I].Options = Options) and IsResizable(I) then + if FColumns[I].BonusPixel <> BonusPixel then begin Dec(Rest, ChangeWidth(I, Sign)); - FColumns[I].FBonusPixel := BonusPixel; + FColumns[I].BonusPixel := BonusPixel; end; Inc(I, Sign); if (BonusPixel and (I > RangeEndCol)) or (not BonusPixel and (I < RangeStartCol)) then begin for I := RangeStartCol to RangeEndCol do - if Options * FColumns[I].FOptions = Options then - FColumns[I].FBonusPixel := not FColumns[I].FBonusPixel; + if Options * FColumns[I].Options = Options then + FColumns[I].BonusPixel := not FColumns[I].BonusPixel; I := Start; end; end; @@ -11705,9 +11755,9 @@ begin // Now set the computed widths. We also compute the result here. Include(FStates, hsResizing); for I := RangeStartCol to RangeEndCol do - if (Options * FColumns[I].FOptions = Options) then + if (Options * FColumns[I].Options = Options) then begin - Inc(Result, Widths[I - RangeStartCol] - FColumns[I].FWidth); + Inc(Result, Widths[I - RangeStartCol] - FColumns[I].Width); FColumns[I].SetWidth(Widths[I - RangeStartCol]); end; Exclude(FStates, hsResizing); @@ -11726,7 +11776,7 @@ var begin with FColumns do for I := Count - 1 downto 0 do - if [coResizable, coVisible] * Items[FPositionToIndex[I]].FOptions = [coResizable, coVisible] then + if [coResizable, coVisible] * Items[FPositionToIndex[I]].Options = [coResizable, coVisible] then Items[I].RestoreLastWidth; end; @@ -11965,7 +12015,7 @@ begin if FOwner.VclStyleEnabled and (seFont in FOwner.StyleElements) then StyleServices.GetElementColor(StyleServices.GetElementDetails(thHeaderItemNormal), ecTextColor, Result) else - Result := FOwner.FHeader.Font.Color; + Result := FOwner.Header.Font.Color; end; //---------------------------------------------------------------------------------------------------------------------- @@ -11983,7 +12033,7 @@ end; function TVTColors.GetSelectedNodeFontColor(Focused: boolean): TColor; begin if Focused then begin - if (tsUseExplorerTheme in FOwner.FStates) and not IsHighContrastEnabled then begin + if (tsUseExplorerTheme in FOwner.TreeStates) and not IsHighContrastEnabled then begin Result := NodeFontColor end else @@ -12034,7 +12084,7 @@ begin if Source is TVTColors then begin FColors := TVTColors(Source).FColors; - if FOwner.FUpdateCount = 0 then + if FOwner.UpdateCount = 0 then FOwner.Invalidate; end else @@ -12189,7 +12239,7 @@ end; //---------------------------------------------------------------------------------------------------------------------- -destructor TBaseVirtualTree.Destroy; +destructor TBaseVirtualTree.Destroy(); var WasValidating: Boolean; begin @@ -12203,15 +12253,15 @@ begin fAccessible := nil; end; - WasValidating := (tsValidating in FStates); + WasValidating := (tsValidating in FStates) or (tsValidationNeeded in FStates); // Checking tsValidating is not enough, the TWorkerThread may be stuck in the first call to ChangeTreeStatesAsync() InterruptValidation(True); if WasValidating then begin // Make sure we dequeue the two synchronized calls from ChangeTreeStatesAsync(), fixes mem leak and AV reported in issue #1001, but is more a workaround. - CheckSynchronize(); - CheckSynchronize(); + while CheckSynchronize() do + Sleep(1); end;// if - Exclude(FOptions.FMiscOptions, toReadOnly); + FOptions.InternalSetMiscOptions(FOptions.MiscOptions - [toReadOnly]); //SetMiscOptions has side effects // Make sure there is no reference remaining to the releasing tree. TWorkerThread.ReleaseThreadReference(); StopWheelPanning; @@ -12365,7 +12415,7 @@ begin VAlign := MulDiv((Integer(NodeHeight[Node]) - VAlign), Node.Align, 100) + VAlign div 2; end else - if toShowButtons in FOptions.FPaintOptions then + if toShowButtons in FOptions.PaintOptions then VAlign := MulDiv((Integer(NodeHeight[Node]) - FPlusBM.Height), Node.Align, 100) + FPlusBM.Height div 2 else VAlign := MulDiv(Integer(Node.NodeHeight), Node.Align, 100); @@ -12419,7 +12469,7 @@ begin ctTriStateCheckBox: begin // Propagate state down to the children. - if toAutoTristateTracking in FOptions.FAutoOptions then + if toAutoTristateTracking in FOptions.AutoOptions then case Value of csUncheckedNormal: if Node.ChildCount > 0 then @@ -12526,7 +12576,7 @@ begin // Propagate state up to the parent. if not (vsInitialized in Parent.States) then InitNode(Parent); - if (toAutoTristateTracking in FOptions.FAutoOptions) and ([vsChecking, vsDisabled] * Parent.States = []) and + if (toAutoTristateTracking in FOptions.AutoOptions) and ([vsChecking, vsDisabled] * Parent.States = []) and (CheckType in [ctCheckBox, ctTriStateCheckBox]) and (Parent <> FRoot) and (Parent.CheckType = ctTriStateCheckBox) then Result := CheckParentCheckState(Node, Value) @@ -12589,8 +12639,8 @@ begin // Initialize short hand variables to speed up tests below. DoSwitch := ssCtrl in FDrawSelShiftState; - AutoSpan := FHeader.UseColumns and (toAutoSpanColumns in FOptions.FAutoOptions); - SimpleSelection := toSimpleDrawSelection in FOptions.FSelectionOptions; + AutoSpan := FHeader.UseColumns and (toAutoSpanColumns in FOptions.AutoOptions); + SimpleSelection := toSimpleDrawSelection in FOptions.SelectionOptions; // This is the node to start with. Run := GetNodeAt(0, MinY, False, CurrentTop); @@ -12608,7 +12658,7 @@ begin // Simple selection allows to draw the selection rectangle anywhere. No intersection with node captions is // required. Only top and bottom bounds of the rectangle matter. - if SimpleSelection or (toFullRowSelect in FOptions.FSelectionOptions) then + if SimpleSelection or (toFullRowSelect in FOptions.SelectionOptions) then begin IsInOldRect := (NextTop > OldRect.Top) and (CurrentTop < OldRect.Bottom) and ((FHeader.Columns.Count = 0) or (FHeader.Columns.TotalWidth > OldRect.Left)) and ((NodeLeft + LabelOffset) < OldRect.Right); @@ -12620,7 +12670,7 @@ begin // The right column border might be extended if column spanning is enabled. if AutoSpan then begin - with FHeader.FColumns do + with FHeader.Columns do begin NextColumn := MainColumn; repeat @@ -12742,22 +12792,22 @@ begin // Initialize short hand variables to speed up tests below. DoSwitch := ssCtrl in FDrawSelShiftState; - WithCheck := (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages); + WithCheck := (toCheckSupport in FOptions.MiscOptions) and Assigned(FCheckImages); // Don't check the events here as descendant trees might have overriden the DoGetImageIndex method. WithStateImages := Assigned(FStateImages) or Assigned(OnGetImageIndexEx); if WithCheck then CheckOffset := FCheckImages.Width + FImagesMargin else CheckOffset := 0; - AutoSpan := FHeader.UseColumns and (toAutoSpanColumns in FOptions.FAutoOptions); - SimpleSelection := toSimpleDrawSelection in FOptions.FSelectionOptions; + AutoSpan := FHeader.UseColumns and (toAutoSpanColumns in FOptions.AutoOptions); + SimpleSelection := toSimpleDrawSelection in FOptions.SelectionOptions; // This is the node to start with. Run := GetNodeAt(0, MinY, False, CurrentTop); if Assigned(Run) then begin // The initial minimal left border is determined by the identation level of the node and is dynamically adjusted. - if toShowRoot in FOptions.FPaintOptions then + if toShowRoot in FOptions.PaintOptions then Dec(NodeRight, Integer((GetNodeLevel(Run) + 1) * FIndent) + FMargin) else Dec(NodeRight, Integer(GetNodeLevel(Run) * FIndent) + FMargin); @@ -12788,16 +12838,16 @@ begin begin NextColumn := MainColumn; repeat - Dummy := FHeader.FColumns.GetPreviousVisibleColumn(NextColumn); + Dummy := FHeader.Columns.GetPreviousVisibleColumn(NextColumn); if (Dummy = InvalidColumn) or not ColumnIsEmpty(Run, Dummy) or - (FHeader.FColumns[Dummy].BiDiMode = bdLeftToRight) then + (FHeader.Columns[Dummy].BiDiMode = bdLeftToRight) then Break; NextColumn := Dummy; until False; if NextColumn = MainColumn then CurrentLeft := NodeLeft else - FHeader.FColumns.GetColumnBounds(NextColumn, CurrentLeft, Dummy); + FHeader.Columns.GetColumnBounds(NextColumn, CurrentLeft, Dummy); end else CurrentLeft := NodeLeft; @@ -12915,7 +12965,7 @@ begin end else begin - if (poDrawSelection in PaintOptions) and (toFullRowSelect in FOptions.FSelectionOptions) and + if (poDrawSelection in PaintOptions) and (toFullRowSelect in FOptions.SelectionOptions) and (vsSelected in Node.States) and not (toUseBlendedSelection in FOptions.PaintOptions) and not (tsUseExplorerTheme in FStates) then begin @@ -12925,7 +12975,7 @@ begin FillRect(Rect(R.Left, R.Bottom - 1, R.Right, R.Bottom)); Dec(R.Bottom); end; - if Focused or (toPopupMode in FOptions.FPaintOptions) then + if Focused or (toPopupMode in FOptions.PaintOptions) then begin Brush.Color := FColors.FocusedSelectionColor; Pen.Color := FColors.FocusedSelectionBorderColor; @@ -12973,10 +13023,10 @@ begin else begin if HasAsParent(Node1, Node2) then - Result := IfThen(ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions), -1, 1) + Result := IfThen(ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions), -1, 1) else if HasAsParent(Node2, Node1) then - Result := IfThen(ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions), 1, -1) + Result := IfThen(ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions), 1, -1) else begin // the given nodes are neither equal nor are they parents of each other, so go up to FRoot @@ -13292,8 +13342,8 @@ end; function TBaseVirtualTree.GetSyncCheckstateWithSelection(Node: PVirtualNode): Boolean; begin - Result := (toSyncCheckboxesWithSelection in FOptions.FSelectionOptions) - and (toCheckSupport in FOptions.FMiscOptions) + Result := (toSyncCheckboxesWithSelection in FOptions.SelectionOptions) + and (toCheckSupport in FOptions.MiscOptions) and Assigned(FCheckImages) and (Node.CheckType = ctCheckBox); ; end; @@ -13373,7 +13423,7 @@ function TBaseVirtualTree.GetNodeHeight(Node: PVirtualNode): Cardinal; begin if Assigned(Node) and (Node <> FRoot) then begin - if (toVariableNodeHeight in FOptions.FMiscOptions) and not (vsDeleting in Node.States) then + if (toVariableNodeHeight in FOptions.MiscOptions) and not (vsDeleting in Node.States) then begin if not (vsInitialized in Node.States) then InitNode(Node); @@ -13428,7 +13478,7 @@ begin if not (toFixedIndent in TreeOptions.PaintOptions) then begin // plus Indent lNodeLevel := GetNodeLevel(pNode); - if toShowRoot in FOptions.FPaintOptions then + if toShowRoot in FOptions.PaintOptions then Inc(lNodeLevel); end else @@ -13443,7 +13493,7 @@ begin exit; // right of checkbox, left of state image - if (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages) and (pNode.CheckType <> ctNone) and (pColumn = Header.MainColumn) then + if (toCheckSupport in FOptions.MiscOptions) and Assigned(FCheckImages) and (pNode.CheckType <> ctNone) and (pColumn = Header.MainColumn) then pOffsets[TVTElement.ofsStateImage] := pOffsets[TVTElement.ofsCheckBox] + FCheckImages.Width + fImagesMargin else pOffsets[TVTElement.ofsStateImage] := pOffsets[TVTElement.ofsCheckBox]; @@ -13681,8 +13731,8 @@ begin end else begin - CurrentBidiMode := FHeader.FColumns[MainColumn].BidiMode; - CurrentAlignment := FHeader.FColumns[MainColumn].Alignment; + CurrentBidiMode := FHeader.Columns[MainColumn].BidiMode; + CurrentAlignment := FHeader.Columns[MainColumn].Alignment; end; // Determine initial left border of first node (take column reordering into account). @@ -13690,8 +13740,8 @@ begin begin // The mouse coordinates don't include any horizontal scrolling hence take this also // out from the returned column position. - NodeLeft := FHeader.FColumns[MainColumn].Left + FEffectiveOffsetX; - NodeRight := NodeLeft + FHeader.FColumns[MainColumn].Width; + NodeLeft := FHeader.Columns[MainColumn].Left + FEffectiveOffsetX; + NodeRight := NodeLeft + FHeader.Columns[MainColumn].Width; end else begin @@ -13785,8 +13835,8 @@ procedure TBaseVirtualTree.InitializeFirstColumnValues(var PaintInfo: TVTPaintIn // Determines initial index, position and cell size of the first visible column. begin - PaintInfo.Column := FHeader.FColumns.GetFirstVisibleColumn; - with FHeader.FColumns, PaintInfo do + PaintInfo.Column := FHeader.Columns.GetFirstVisibleColumn; + with FHeader.Columns, PaintInfo do begin if Column > NoColumn then begin @@ -14058,10 +14108,10 @@ var begin SetSize(Size.cx, Size.cy); - if IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions) or VclStyleEnabled then + if IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.PaintOptions) or VclStyleEnabled then begin if (FHeader.MainColumn > NoColumn) then - Brush.Color := FHeader.FColumns[FHeader.MainColumn].GetEffectiveColor + Brush.Color := FHeader.Columns[FHeader.MainColumn].GetEffectiveColor else Brush.Color := FColors.BackGroundColor; end @@ -14077,14 +14127,19 @@ var //--------------- end local function ---------------------------------------- +const + cMinExpandoHeight = 11; // pixels @100% begin if VclStyleEnabled and (seClient in StyleElements) then begin if NeedButtons then begin if StyleServices.GetElementSize(FPlusBM.Canvas.Handle, StyleServices.GetElementDetails(tcbCategoryGlyphClosed), TElementSize.esActual, Size) then + begin + Size.cx := Max(Size.cx, cMinExpandoHeight); // Use min size of 11, see issue #1035 / RSP-33715 Size.cx := ScaledPixels(Size.cx) // I would have expected that the returned value is dpi-sclaed, but this is not the case in RAD Studio 10.4.1. See issue #984 + end else - Size.cx := ScaledPixels(11); + Size.cx := ScaledPixels(cMinExpandoHeight); Size.cy := Size.cx; FillBitmap(FPlusBM); FillBitmap(FHotPlusBM); @@ -14295,9 +14350,9 @@ procedure TBaseVirtualTree.SetAnimationDuration(const Value: Cardinal); begin FAnimationDuration := Value; if FAnimationDuration = 0 then - Exclude(FOptions.FAnimationOptions, toAnimatedToggle) + FOptions.AnimationOptions := FOptions.AnimationOptions - [toAnimatedToggle] else - Include(FOptions.FAnimationOptions, toAnimatedToggle); + FOptions.AnimationOptions := FOptions.AnimationOptions + [toAnimatedToggle] end; //---------------------------------------------------------------------------------------------------------------------- @@ -14482,13 +14537,13 @@ end; procedure TBaseVirtualTree.SetCheckType(Node: PVirtualNode; Value: TCheckType); begin - if (Node.CheckType <> Value) and not (toReadOnly in FOptions.FMiscOptions) then + if (Node.CheckType <> Value) and not (toReadOnly in FOptions.MiscOptions) then begin Node.CheckType := Value; if (Value <> ctTriStateCheckBox) and (Node.CheckState in [csMixedNormal, csMixedPressed]) then Node.CheckState := csUncheckedNormal;// reset check state if it doesn't fit the new check type // For check boxes with tri-state check box parents we have to initialize differently. - if (toAutoTriStateTracking in FOptions.FAutoOptions) and (Value in [ctCheckBox, ctTriStateCheckBox]) and + if (toAutoTriStateTracking in FOptions.AutoOptions) and (Value in [ctCheckBox, ctTriStateCheckBox]) and (Node.Parent <> FRoot) then begin if not (vsInitialized in Node.Parent.States) then @@ -14519,7 +14574,7 @@ var Count: Integer; NewHeight: Integer; begin - if not (toReadOnly in FOptions.FMiscOptions) then + if not (toReadOnly in FOptions.MiscOptions) then begin if Node = nil then Node := FRoot; @@ -14567,7 +14622,7 @@ begin Dec(Remaining); Inc(Index); - if (toVariableNodeHeight in FOptions.FMiscOptions) then + if (toVariableNodeHeight in FOptions.MiscOptions) then GetNodeHeight(Child); Inc(NewHeight, Child.TotalHeight); end; @@ -14577,8 +14632,8 @@ begin AdjustTotalCount(Node, Count, True); Node.ChildCount := NewChildCount; - if (FUpdateCount = 0) and (toAutoSort in FOptions.FAutoOptions) and (FHeader.FSortColumn > InvalidColumn) then - Sort(Node, FHeader.FSortColumn, FHeader.FSortDirection, True); + if (FUpdateCount = 0) and (toAutoSort in FOptions.AutoOptions) and (FHeader.SortColumn > InvalidColumn) then + Sort(Node, FHeader.SortColumn, FHeader.SortDirection, True); InvalidateCache; end//if NewChildCount > Node.ChildCount @@ -14770,7 +14825,7 @@ begin InvalidateColumn(FFocusedColumn); InvalidateColumn(Value); FFocusedColumn := Value; - if Assigned(FFocusedNode) and not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions) then + if Assigned(FFocusedNode) and not (toDisableAutoscrollOnFocus in FOptions.AutoOptions) then begin if ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions, True) then InvalidateNode(FFocusedNode); @@ -14830,7 +14885,7 @@ end; procedure TBaseVirtualTree.SetHasChildren(Node: PVirtualNode; Value: Boolean); begin - if Assigned(Node) and not (toReadOnly in FOptions.FMiscOptions) then + if Assigned(Node) and not (toReadOnly in FOptions.MiscOptions) then begin if Value then Include(Node.States, vsHasChildren) @@ -14882,7 +14937,7 @@ begin if Value then begin Include(Node.States, vsFiltered); - if not (toShowFilteredNodes in FOptions.FPaintOptions) then + if not (toShowFilteredNodes in FOptions.PaintOptions) then begin if (vsInitializing in Node.States) and not (vsHasChildren in Node.States) then AdjustTotalHeight(Node, 0, False) @@ -14905,7 +14960,7 @@ begin else begin Exclude(Node.States, vsFiltered); - if not (toShowFilteredNodes in FOptions.FPaintOptions) then + if not (toShowFilteredNodes in FOptions.PaintOptions) then begin AdjustTotalHeight(Node, Integer(NodeHeight[Node]), True); if FullyVisible[Node] then @@ -15249,7 +15304,7 @@ begin if FSelectionCount = 0 then FRangeAnchor := Node else begin - if not (toMultiSelect in FOptions.FSelectionOptions) then + if not (toMultiSelect in FOptions.SelectionOptions) then ClearSelection; if FRangeAnchor = nil then FRangeAnchor := Node; @@ -15257,7 +15312,7 @@ begin AddToSelection(Node, True); - if not (toMultiSelect in FOptions.FSelectionOptions) then + if not (toMultiSelect in FOptions.SelectionOptions) then FocusedNode := GetFirstSelected; // if only one node can be selected, make sure the focused node changes with the selected node // Make sure there is a valid column selected (if there are columns at all). if ((FFocusedColumn < 0) or not (coVisible in FHeader.Columns[FFocusedColumn].Options)) and @@ -15555,6 +15610,13 @@ end; //---------------------------------------------------------------------------------------------------------------------- +//used by TCustomVirtualTreeOptions +procedure TBaseVirtualTree.SetVisibleCount(value : Cardinal); +begin + FVisibleCount := value; +end; + + procedure TBaseVirtualTree.TileBackground(Source: TPicture; Target: TCanvas; Offset: TPoint; R: TRect; aBkgColor: TColor); // Draws the given source graphic so that it tiles into the given rectangle which is relative to the target bitmap. @@ -15624,7 +15686,7 @@ var LocalBrush: HBRUSH; begin - with TToggleAnimationData(Data^), FHeader.FColumns do + with TToggleAnimationData(Data^), FHeader.Columns do begin // Iterate through all columns and erase background in their local color. // LocalBrush is a brush in the color of the particular column. @@ -15632,7 +15694,7 @@ var while (Column > InvalidColumn) and (Run.Left < ClientWidth) do begin GetColumnBounds(Column, Run.Left, Run.Right); - if coParentColor in Items[Column].FOptions then + if coParentColor in Items[Column].Options then FillRect(DC, Run, Brush) else begin @@ -15755,8 +15817,8 @@ begin if FEffectiveOffsetX < 0 then FEffectiveOffsetX := 0; - if toAutoBidiColumnOrdering in FOptions.FAutoOptions then - FHeader.FColumns.ReorderColumns(UseRightToLeftAlignment); + if toAutoBidiColumnOrdering in FOptions.AutoOptions then + FHeader.Columns.ReorderColumns(UseRightToLeftAlignment); FHeader.Invalidate(nil); end; @@ -15981,15 +16043,15 @@ begin //workaround for issue #291 //it duplicates parts of the following code and code in TVirtualTreeHintWindow HintStr := ''; - if FHeader.UseColumns and (hoShowHint in FHeader.FOptions) and FHeader.InHeader(CursorPos) then + if FHeader.UseColumns and (hoShowHint in FHeader.Options) and FHeader.InHeader(CursorPos) then begin CursorRect := FHeaderRect; // Convert the cursor rectangle into real client coordinates. - OffsetRect(CursorRect, 0, -Integer(FHeader.FHeight)); - HitInfo.HitColumn := FHeader.FColumns.GetColumnAndBounds(CursorPos, CursorRect.Left, CursorRect.Right); + OffsetRect(CursorRect, 0, -Integer(FHeader.Height)); + HitInfo.HitColumn := FHeader.Columns.GetColumnAndBounds(CursorPos, CursorRect.Left, CursorRect.Right); if (HitInfo.HitColumn > NoColumn) and not (csLButtonDown in ControlState) and - (FHeader.FColumns[HitInfo.HitColumn].FHint <> '') then - HintStr := FHeader.FColumns[HitInfo.HitColumn].FHint; + (FHeader.Columns[HitInfo.HitColumn].Hint <> '') then + HintStr := FHeader.Columns[HitInfo.HitColumn].Hint; end else if HintMode = hmDefault then @@ -16004,12 +16066,12 @@ begin end; // First check whether there is a header hint to show. - if FHeader.UseColumns and (hoShowHint in FHeader.FOptions) and FHeader.InHeader(CursorPos) then + if FHeader.UseColumns and (hoShowHint in FHeader.Options) and FHeader.InHeader(CursorPos) then begin CursorRect := FHeaderRect; // Convert the cursor rectangle into real client coordinates. - OffsetRect(CursorRect, 0, -Integer(FHeader.FHeight)); - HitInfo.HitColumn := FHeader.FColumns.GetColumnAndBounds(CursorPos, CursorRect.Left, CursorRect.Right); + OffsetRect(CursorRect, 0, -Integer(FHeader.Height)); + HitInfo.HitColumn := FHeader.Columns.GetColumnAndBounds(CursorPos, CursorRect.Left, CursorRect.Right); // align the vertical hint position on the bottom bound of the header, but // avoid overlapping of mouse cursor and hint HintPos.Y := Max(HintPos.Y, ClientToScreen(Point(0, CursorRect.Bottom)).Y); @@ -16018,9 +16080,9 @@ begin // cancel this with ESC. if (HitInfo.HitColumn > NoColumn) and not (csLButtonDown in ControlState) then begin - HintStr := FHeader.FColumns[HitInfo.HitColumn].FHint; + HintStr := FHeader.Columns[HitInfo.HitColumn].Hint; if HintStr = '' then - with FHeader.FColumns[HitInfo.HitColumn] do + with FHeader.Columns[HitInfo.HitColumn] do begin if (2 * FMargin + CaptionWidth + 1) >= Width then HintStr := FCaptionText; @@ -16060,19 +16122,19 @@ begin begin if HitInfo.HitColumn > NoColumn then begin - FHeader.FColumns.GetColumnBounds(HitInfo.HitColumn, ColLeft, ColRight); + FHeader.Columns.GetColumnBounds(HitInfo.HitColumn, ColLeft, ColRight); // The right column border might be extended if column spanning is enabled. - if toAutoSpanColumns in FOptions.FAutoOptions then + if toAutoSpanColumns in FOptions.AutoOptions then begin SpanColumn := HitInfo.HitColumn; repeat - Dummy := FHeader.FColumns.GetNextVisibleColumn(SpanColumn); + Dummy := FHeader.Columns.GetNextVisibleColumn(SpanColumn); if (Dummy = InvalidColumn) or not ColumnIsEmpty(HitInfo.HitNode, Dummy) then Break; SpanColumn := Dummy; until False; if SpanColumn <> HitInfo.HitColumn then - FHeader.FColumns.GetColumnBounds(SpanColumn, Dummy, ColRight); + FHeader.Columns.GetColumnBounds(SpanColumn, Dummy, ColRight); end; end else @@ -16228,16 +16290,16 @@ begin if Assigned(FCurrentHotNode) then begin DoHotChange(FCurrentHotNode, nil); - if (toHotTrack in FOptions.PaintOptions) or (toCheckSupport in FOptions.FMiscOptions) then + if (toHotTrack in FOptions.PaintOptions) or (toCheckSupport in FOptions.MiscOptions) then InvalidateNode(FCurrentHotNode); FCurrentHotNode := nil; end; if Assigned(Header) then begin - Header.FColumns.FDownIndex := NoColumn; - Header.FColumns.FHoverIndex := NoColumn; - Header.FColumns.FCheckBoxHit := False; + Header.FColumns.DownIndex := NoColumn; + Header.FColumns.HoverIndex := NoColumn; + Header.FColumns.CheckBoxHit := False; end; DoMouseLeave(); inherited; @@ -16610,9 +16672,9 @@ begin UpdateHorizontalScrollBar(False); end; SB_LINELEFT: - SetOffsetX(FOffsetX + RTLFactor * FScrollBarOptions.FIncrementX); + SetOffsetX(FOffsetX + RTLFactor * FScrollBarOptions.HorizontalIncrement); SB_LINERIGHT: - SetOffsetX(FOffsetX - RTLFactor * FScrollBarOptions.FIncrementX); + SetOffsetX(FOffsetX - RTLFactor * FScrollBarOptions.HorizontalIncrement); SB_PAGELEFT: SetOffsetX(FOffsetX + RTLFactor * (ClientWidth - FHeader.Columns.GetVisibleFixedWidth)); SB_PAGERIGHT: @@ -16676,7 +16738,7 @@ var begin if (not assigned(anode)) or (not FHeader.UseColumns) - or (not (toAutoSpanColumns in FOptions.FAutoOptions)) + or (not (toAutoSpanColumns in FOptions.AutoOptions)) or (acolumn = FHeader.MainColumn) then begin //previously existing logic @@ -16684,7 +16746,7 @@ var exit; end; //consider auto spanning - with FHeader.FColumns do //standard loop for auto span + with FHeader.Columns do //standard loop for auto span begin PrevColumn := acolumn; repeat @@ -16707,7 +16769,7 @@ var begin if (not assigned(anode)) or (not FHeader.UseColumns) - or (not (toAutoSpanColumns in FOptions.FAutoOptions)) + or (not (toAutoSpanColumns in FOptions.AutoOptions)) or (acolumn = FHeader.MainColumn) then begin //previously existing logic @@ -16715,7 +16777,7 @@ var exit; end; //consider auto spanning - with FHeader.FColumns do //standard loop for auto span + with FHeader.Columns do //standard loop for auto span begin NextColumn := acolumn; repeat @@ -16739,10 +16801,10 @@ var result := false; if (not assigned(anode)) or (not FHeader.UseColumns) - or (not (toAutoSpanColumns in FOptions.FAutoOptions)) + or (not (toAutoSpanColumns in FOptions.AutoOptions)) or (acolumn = FHeader.MainColumn) then exit; - with FHeader.FColumns do + with FHeader.Columns do begin previousColumn := FHeader.Columns.GetPreviousVisibleColumn(acolumn); if (previousColumn = InvalidColumn) //there is no previous column @@ -16769,15 +16831,15 @@ begin begin if (CharCode in [VK_HOME, VK_END, VK_PRIOR, VK_NEXT, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_BACK, VK_TAB]) and (RootNode.FirstChild <> nil) then begin - PerformMultiSelect := (ssShift in Shift) and (toMultiSelect in FOptions.FSelectionOptions) and not IsEditing; + PerformMultiSelect := (ssShift in Shift) and (toMultiSelect in FOptions.SelectionOptions) and not IsEditing; // Flag to avoid range selection in case of single node advance. DoRangeSelect := (CharCode in [VK_HOME, VK_END, VK_PRIOR, VK_NEXT]) and PerformMultiSelect and not IsEditing; NeedInvalidate := DoRangeSelect or (FSelectionCount > 1); - ActAsGrid := toGridExtensions in FOptions.FMiscOptions; + ActAsGrid := toGridExtensions in FOptions.MiscOptions; ClearPending := (Shift = []) or (ActAsGrid and not (ssShift in Shift)) or - not (toMultiSelect in FOptions.FSelectionOptions) or (CharCode in [VK_TAB, VK_BACK]); + not (toMultiSelect in FOptions.SelectionOptions) or (CharCode in [VK_TAB, VK_BACK]); // Keep old focused node for range selection. Use a default node if none was focused until now. LastFocused := FFocusedNode; @@ -16801,15 +16863,15 @@ begin begin if (CharCode = VK_END) xor UseRightToLeftAlignment then begin - GetStartColumn := FHeader.FColumns.GetLastVisibleColumn; - GetNextColumn := FHeader.FColumns.GetPreviousVisibleColumn; + GetStartColumn := FHeader.Columns.GetLastVisibleColumn; + GetNextColumn := FHeader.Columns.GetPreviousVisibleColumn; GetNextNode := GetPreviousVisible; Node := GetLastVisible(nil, True); end else begin - GetStartColumn := FHeader.FColumns.GetFirstVisibleColumn; - GetNextColumn := FHeader.FColumns.GetNextVisibleColumn; + GetStartColumn := FHeader.Columns.GetFirstVisibleColumn; + GetNextColumn := FHeader.Columns.GetNextVisibleColumn; GetNextNode := GetNextVisible; Node := GetFirstVisible(nil, True); end; @@ -16830,7 +16892,7 @@ begin if (Shift = [ssCtrl]) and not ActAsGrid then begin ScrollIntoView(Node, toCenterScrollIntoView in FOptions.SelectionOptions, - not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions)); + not (toDisableAutoscrollOnFocus in FOptions.AutoOptions)); if (CharCode = VK_HOME) and not UseRightToLeftAlignment then SetOffsetX(0) else @@ -16842,9 +16904,9 @@ begin FocusedNode := Node; //fix: In grid mode, if full row select option is ON, //then also go to the node determined from the earlier logic - if ActAsGrid and (toFullRowSelect in FOptions.FSelectionOptions) then + if ActAsGrid and (toFullRowSelect in FOptions.SelectionOptions) then FocusedNode := Node; - if ActAsGrid and not (toFullRowSelect in FOptions.FSelectionOptions) then + if ActAsGrid and not (toFullRowSelect in FOptions.SelectionOptions) then begin FocusedColumn := NewColumn; // fix: If auto span is ON the last column may be a merged column. So take @@ -16862,18 +16924,18 @@ begin if [ssShift, ssAlt] = Shift then begin if FFocusedColumn <= NoColumn then - NewColumn := FHeader.FColumns.GetFirstVisibleColumn + NewColumn := FHeader.Columns.GetFirstVisibleColumn else begin - Offset := FHeader.FColumns.GetVisibleFixedWidth; + Offset := FHeader.Columns.GetVisibleFixedWidth; NewColumn := FFocusedColumn; while True do begin - TempColumn := FHeader.FColumns.GetPreviousVisibleColumn(NewColumn); - NewWidth := FHeader.FColumns[NewColumn].Width; + TempColumn := FHeader.Columns.GetPreviousVisibleColumn(NewColumn); + NewWidth := FHeader.Columns[NewColumn].Width; if (TempColumn <= NoColumn) or (Offset + NewWidth >= ClientWidth) or - (coFixed in FHeader.FColumns[TempColumn].FOptions) then + (coFixed in FHeader.Columns[TempColumn].Options) then Break; NewColumn := TempColumn; Inc(Offset, NewWidth); @@ -16913,18 +16975,18 @@ begin if [ssShift, ssAlt] = Shift then begin if FFocusedColumn <= NoColumn then - NewColumn := FHeader.FColumns.GetFirstVisibleColumn + NewColumn := FHeader.Columns.GetFirstVisibleColumn else begin - Offset := FHeader.FColumns.GetVisibleFixedWidth; + Offset := FHeader.Columns.GetVisibleFixedWidth; NewColumn := FFocusedColumn; while True do begin - TempColumn := FHeader.FColumns.GetNextVisibleColumn(NewColumn); - NewWidth := FHeader.FColumns[NewColumn].Width; + TempColumn := FHeader.Columns.GetNextVisibleColumn(NewColumn); + NewWidth := FHeader.Columns[NewColumn].Width; if (TempColumn <= NoColumn) or (Offset + NewWidth >= ClientWidth) or - (coFixed in FHeader.FColumns[TempColumn].FOptions) then + (coFixed in FHeader.Columns[TempColumn].Options) then Break; NewColumn := TempColumn; Inc(Offset, NewWidth); @@ -17020,7 +17082,7 @@ begin begin // other special cases Context := NoColumn; - if (toExtendedFocus in FOptions.FSelectionOptions) and (toGridExtensions in FOptions.FMiscOptions) then + if (toExtendedFocus in FOptions.SelectionOptions) and (toGridExtensions in FOptions.MiscOptions) then begin Context := getPreviousVisibleAutoSpanColumn(FFocusedColumn, FFocusedNode); if Context > NoColumn then @@ -17070,7 +17132,7 @@ begin begin // other special cases Context := NoColumn; - if (toExtendedFocus in FOptions.FSelectionOptions) and (toGridExtensions in FOptions.FMiscOptions) then + if (toExtendedFocus in FOptions.SelectionOptions) and (toGridExtensions in FOptions.MiscOptions) then begin Context := getNextVisibleAutoSpanColumn(FFocusedColumn, FFocusedNode); if Context > NoColumn then @@ -17108,20 +17170,20 @@ begin if Assigned(FFocusedNode) and (FFocusedNode.Parent <> FRoot) then FocusedNode := FocusedNode.Parent; VK_TAB: - if (toExtendedFocus in FOptions.FSelectionOptions) and FHeader.UseColumns then + if (toExtendedFocus in FOptions.SelectionOptions) and FHeader.UseColumns then begin // In order to avoid duplicating source code just to change the direction // we use function variables. if ssShift in Shift then begin - GetStartColumn := FHeader.FColumns.GetLastVisibleColumn; - GetNextColumn := FHeader.FColumns.GetPreviousVisibleColumn; + GetStartColumn := FHeader.Columns.GetLastVisibleColumn; + GetNextColumn := FHeader.Columns.GetPreviousVisibleColumn; GetNextNode := GetPreviousVisible; end else begin - GetStartColumn := FHeader.FColumns.GetFirstVisibleColumn; - GetNextColumn := FHeader.FColumns.GetNextVisibleColumn; + GetStartColumn := FHeader.Columns.GetFirstVisibleColumn; + GetNextColumn := FHeader.Columns.GetNextVisibleColumn; GetNextNode := GetNextVisible; end; @@ -17282,7 +17344,7 @@ begin CancelEditNode; end; VK_SPACE: - if (toCheckSupport in FOptions.FMiscOptions) and Assigned(FFocusedNode) and + if (toCheckSupport in FOptions.MiscOptions) and Assigned(FFocusedNode) and (FFocusedNode.CheckType <> ctNone) then begin NewCheckState := DetermineNextCheckState(FFocusedNode.CheckType, GetCheckState(FFocusedNode)); @@ -17406,7 +17468,7 @@ begin tsMiddleButtonDown, tsOLEDragPending, tsVCLDragPending, tsIncrementalSearching, tsNodeHeightTrackPending, tsNodeHeightTracking]); - if (FSelectionCount > 0) or not (toGhostedIfUnfocused in FOptions.FPaintOptions) then + if (FSelectionCount > 0) or not (toGhostedIfUnfocused in FOptions.PaintOptions) then Invalidate else if Assigned(FFocusedNode) then @@ -17498,7 +17560,7 @@ begin inherited; // get information about the hit - if toMiddleClickSelect in FOptions.FSelectionOptions then + if toMiddleClickSelect in FOptions.SelectionOptions then begin GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); HandleMouseDblClick(Message, HitInfo); @@ -17516,12 +17578,12 @@ var begin DoStateChange([tsMiddleButtonDown]); - if FHeader.FStates = [] then + if FHeader.States = [] then begin inherited; // Start wheel panning or scrolling if not already active, allowed and scrolling is useful at all. - if (toWheelPanning in FOptions.FMiscOptions) and ([tsWheelScrolling, tsWheelPanning] * FStates = []) and + if (toWheelPanning in FOptions.MiscOptions) and ([tsWheelScrolling, tsWheelPanning] * FStates = []) and ((Integer(FRangeX) > ClientWidth) or (Integer(FRangeY) > ClientHeight)) then begin FLastClickPos := SmallPointToPoint(Message.Pos); @@ -17532,7 +17594,7 @@ begin StopWheelPanning; // Get information about the hit. - if toMiddleClickSelect in FOptions.FSelectionOptions then + if toMiddleClickSelect in FOptions.SelectionOptions then begin GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); HandleMouseDown(Message, HitInfo); @@ -17561,12 +17623,12 @@ begin StopWheelPanning; end else - if FHeader.FStates = [] then + if FHeader.States = [] then begin inherited; // get information about the hit - if toMiddleClickSelect in FOptions.FSelectionOptions then + if toMiddleClickSelect in FOptions.SelectionOptions then begin GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); HandleMouseUp(Message, HitInfo); @@ -17582,7 +17644,7 @@ begin inherited; with FHeader do - if hoVisible in FHeader.FOptions then + if hoVisible in FHeader.Options then with Message.CalcSize_Params^ do Inc(rgrc[0].Top, FHeight); end; @@ -17600,7 +17662,7 @@ begin StopTimer(ChangeTimer); StopTimer(StructureChangeTimer); - if not (csDesigning in ComponentState) and (toAcceptOLEDrop in FOptions.FMiscOptions) then + if not (csDesigning in ComponentState) and (toAcceptOLEDrop in FOptions.MiscOptions) then RevokeDragDrop(Handle); // Clean up other stuff. @@ -17615,7 +17677,7 @@ procedure TBaseVirtualTree.WMNCHitTest(var Message: TWMNCHitTest); begin inherited; - if (hoVisible in FHeader.FOptions) and + if (hoVisible in FHeader.Options) and FHeader.InHeader(ScreenToClient(SmallPointToPoint(Message.Pos))) then Message.Result := HTBORDER; end; @@ -17699,12 +17761,12 @@ begin if tsVCLDragging in FStates then ImageList_DragShowNolock(True); - if hoVisible in FHeader.FOptions then + if hoVisible in FHeader.Options then begin DC := GetDCEx(Handle, 0, DCX_CACHE or DCX_CLIPSIBLINGS or DCX_WINDOW or DCX_VALIDATE); if DC <> 0 then try - FHeader.FColumns.PaintHeader(DC, FHeaderRect, -FEffectiveOffsetX); + FHeader.Columns.PaintHeader(DC, FHeaderRect, -FEffectiveOffsetX); finally ReleaseDC(Handle, DC); end; @@ -17778,7 +17840,7 @@ begin inherited; // get information about the hit - if toMiddleClickSelect in FOptions.FSelectionOptions then + if toMiddleClickSelect in FOptions.SelectionOptions then begin GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); HandleMouseDblClick(Message, HitInfo); @@ -17797,12 +17859,12 @@ var begin DoStateChange([tsRightButtonDown]); - if FHeader.FStates = [] then + if FHeader.States = [] then begin inherited; // get information about the hit - if toRightClickSelect in FOptions.FSelectionOptions then + if toRightClickSelect in FOptions.SelectionOptions then begin GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); // Go temporarily into sync mode to avoid a delayed change event for the node when selecting. #679 @@ -17827,7 +17889,7 @@ var begin DoStateChange([], [tsPopupMenuShown, tsRightButtonDown]); - if FHeader.FStates = [] then + if FHeader.States = [] then begin Application.CancelHint; @@ -17843,7 +17905,7 @@ begin // get information about the hit GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo); - if toRightClickSelect in FOptions.FSelectionOptions then + if toRightClickSelect in FOptions.SelectionOptions then HandleMouseUp(Message, HitInfo); if not Assigned(PopupMenu) then @@ -17880,7 +17942,7 @@ begin if not (csDesigning in ComponentState) then begin NewCursor := crDefault; - if (toNodeHeightResize in FOptions.FMiscOptions) then + if (toNodeHeightResize in FOptions.MiscOptions) then begin GetCursorPos(P); P := ScreenToClient(P); @@ -17926,7 +17988,7 @@ procedure TBaseVirtualTree.WMSetFocus(var Msg: TWMSetFocus); begin inherited; - if (FSelectionCount > 0) or not (toGhostedIfUnfocused in FOptions.FPaintOptions) then + if (FSelectionCount > 0) or not (toGhostedIfUnfocused in FOptions.PaintOptions) then Invalidate; end; @@ -18061,9 +18123,9 @@ begin RedrawWindow(Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE or RDW_NOERASE or RDW_NOCHILDREN); end; SB_LINEUP: - SetOffsetY(FOffsetY + FScrollBarOptions.FIncrementY); + SetOffsetY(FOffsetY + FScrollBarOptions.VerticalIncrement); SB_LINEDOWN: - SetOffsetY(FOffsetY - FScrollBarOptions.FIncrementY); + SetOffsetY(FOffsetY - FScrollBarOptions.VerticalIncrement); SB_PAGEUP: SetOffsetY(FOffsetY + ClientHeight); SB_PAGEDOWN: @@ -18152,7 +18214,7 @@ procedure TBaseVirtualTree.AdjustPaintCellRect(var PaintInfo: TVTPaintInfo; var begin // Since cells are always drawn from left to right the next column index is independent of the // bidi mode, but not the column borders, which might change depending on the cell's content. - NextNonEmpty := FHeader.FColumns.GetNextVisibleColumn(PaintInfo.Column); + NextNonEmpty := FHeader.Columns.GetNextVisibleColumn(PaintInfo.Column); end; //---------------------------------------------------------------------------------------------------------------------- @@ -18445,8 +18507,8 @@ begin IsDropTarget := Assigned(FDragManager) and DragManager.IsDropTarget; IsDrawSelecting := [tsDrawSelPending, tsDrawSelecting] * FStates <> []; IsWheelPanning := [tsWheelPanning, tsWheelScrolling] * FStates <> []; - Result := ((toAutoScroll in FOptions.FAutoOptions) or IsWheelPanning) and - (FHeader.FStates = []) and (IsDrawSelecting or IsDropTarget or (tsVCLDragging in FStates) or IsWheelPanning); + Result := ((toAutoScroll in FOptions.AutoOptions) or IsWheelPanning) and + (FHeader.States = []) and (IsDrawSelecting or IsDropTarget or (tsVCLDragging in FStates) or IsWheelPanning); end; //---------------------------------------------------------------------------------------------------------------------- @@ -18464,8 +18526,8 @@ end; function TBaseVirtualTree.CanSplitterResizeNode(P: TPoint; Node: PVirtualNode; Column: TColumnIndex): Boolean; begin - Result := (toNodeHeightResize in FOptions.FMiscOptions) and Assigned(Node) and (Node <> FRoot) and - (Column > NoColumn) and (coFixed in FHeader.FColumns[Column].FOptions); + Result := (toNodeHeightResize in FOptions.MiscOptions) and Assigned(Node) and (Node <> FRoot) and + (Column > NoColumn) and (coFixed in FHeader.Columns[Column].Options); DoCanSplitterResizeNode(P, Node, Column, Result); end; @@ -18494,10 +18556,8 @@ const {$ifend} var Flags: TScalingFlags; - Run: PVirtualNode; - lNewNodeTotalHeight: Cardinal; begin - if (toAutoChangeScale in FOptions.FAutoOptions) then + if (toAutoChangeScale in FOptions.AutoOptions) then begin if (M <> D) then begin @@ -18520,27 +18580,7 @@ begin FCheckImages := CreateSystemImageSet(Self); end; UpdateHeaderRect(); - // Scale also node heights - BeginUpdate(); - try - Run := GetFirst(); - while Assigned(Run) do - begin - if vsInitialized in Run.States then - SetNodeHeight(Run, MulDiv(Run.NodeHeight, M, D)) - else // prevent initialization of non-initialzed nodes - begin - Run.NodeHeight := MulDiv(Run.NodeHeight, M, D); - // The next three lines fix issue #1000 - lNewNodeTotalHeight := MulDiv(Run.TotalHeight, M, D); - FRoot.TotalHeight := FRoot.TotalHeight + lNewNodeTotalHeight - Run.TotalHeight; // 1 EIntOverflow exception seen here in debug build in 01/2021 - Run.TotalHeight := lNewNodeTotalHeight; - end; - Run := GetNextNoInit(Run); - end; // while - finally - EndUpdate(); - end; + ScaleNodeHeights(M, D); end;//if sfHeight end;// if M<>D end;//if toAutoChangeScale @@ -18551,6 +18591,34 @@ begin AutoScale(M <> D); end; + +procedure TBaseVirtualTree.ScaleNodeHeights(M, D: Integer); +var + Run: PVirtualNode; + lNewNodeTotalHeight: Cardinal; +begin + // Scale also node heights + BeginUpdate(); + try + Run := GetFirst(); + while Assigned(Run) do + begin + if vsInitialized in Run.States then + SetNodeHeight(Run, MulDiv(Run.NodeHeight, M, D)) + else // prevent initialization of non-initialzed nodes + begin + Run.NodeHeight := MulDiv(Run.NodeHeight, M, D); + // The next three lines fix issue #1000 + lNewNodeTotalHeight := MulDiv(Run.TotalHeight, M, D); + FRoot.TotalHeight := FRoot.TotalHeight + lNewNodeTotalHeight - Run.TotalHeight; // 1 EIntOverflow exception seen here in debug build in 01/2021 + Run.TotalHeight := lNewNodeTotalHeight; + end; + Run := GetNextNoInit(Run); + end; // while + finally + EndUpdate(); + end; +end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ChangeTreeStatesAsync(EnterStates, LeaveStates: TVirtualTreeStates); @@ -18755,7 +18823,7 @@ begin with Params do begin Style := Style or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or ScrollBar[ScrollBarOptions.FScrollBars]; - if toFullRepaintOnResize in FOptions.FMiscOptions then + if toFullRepaintOnResize in FOptions.MiscOptions then WindowClass.style := WindowClass.style or CS_HREDRAW or CS_VREDRAW else WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW); @@ -18794,7 +18862,7 @@ begin if ((StyleServices.Enabled ) and (toThemeAware in TreeOptions.PaintOptions) ) then begin DoStateChange([tsUseThemes]); - if (toUseExplorerTheme in FOptions.FPaintOptions) and IsWinVistaOrAbove then + if (toUseExplorerTheme in FOptions.PaintOptions) and IsWinVistaOrAbove then begin DoStateChange([tsUseExplorerTheme]); SetWindowTheme('explorer'); @@ -18807,15 +18875,15 @@ begin // Because of the special recursion and update stopper when creating the window (or resizing it) // we have to manually trigger the auto size calculation here. - if hsNeedScaling in FHeader.FStates then + if hsNeedScaling in FHeader.States then FHeader.RescaleHeader; - if hoAutoResize in FHeader.FOptions then - FHeader.FColumns.AdjustAutoSize(InvalidColumn); + if hoAutoResize in FHeader.Options then + FHeader.Columns.AdjustAutoSize(InvalidColumn); PrepareBitmaps(True, True); // Register tree as OLE drop target. - if not (csDesigning in ComponentState) and (toAcceptOLEDrop in FOptions.FMiscOptions) then + if not (csDesigning in ComponentState) and (toAcceptOLEDrop in FOptions.MiscOptions) then if not (csLoading in ComponentState) then // will be done in Loaded after all inherited settings are loaded from the DFMs RegisterDragDrop(Handle, DragManager as IDropTarget); @@ -18881,17 +18949,17 @@ var begin ImageHit := HitInfo.HitPositions * [hiOnNormalIcon, hiOnStateIcon] <> []; LabelHit := hiOnItemLabel in HitInfo.HitPositions; - ItemHit := ((hiOnItem in HitInfo.HitPositions) and - ((toFullRowDrag in FOptions.FMiscOptions) or (toFullRowSelect in FOptions.FSelectionOptions))); + ItemHit := (hiOnItem in HitInfo.HitPositions) and ((toFullRowDrag in FOptions.MiscOptions) or + (toFullRowSelect in FOptions.SelectionOptions)); // In report mode only direct hits of the node captions/images in the main column are accepted as hits. - if (toReportMode in FOptions.FMiscOptions) and not (ItemHit or ((LabelHit or ImageHit) and + if (toReportMode in FOptions.MiscOptions) and not (ItemHit or ((LabelHit or ImageHit) and (HitInfo.HitColumn = FHeader.MainColumn))) then HitInfo.HitNode := nil; if Assigned(HitInfo.HitNode) then begin - if LabelHit or ImageHit or not (toShowDropmark in FOptions.FPaintOptions) then + if LabelHit or ImageHit or not (toShowDropmark in FOptions.PaintOptions) then Result := dmOnNode else if ((NodeRect.Top + NodeRect.Bottom) div 2) > P.Y then @@ -18970,7 +19038,7 @@ begin begin // Position is to the left of calculated indentation which can only happen for the main column. // Check whether it corresponds to a button/checkbox. - if (toShowButtons in FOptions.FPaintOptions) and (vsHasChildren in HitInfo.HitNode.States) then + if (toShowButtons in FOptions.PaintOptions) and (vsHasChildren in HitInfo.HitNode.States) then begin // Position of button is interpreted very generously to avoid forcing the user // to click exactly into the 9x9 pixels area. The entire node height and one full @@ -18996,7 +19064,7 @@ begin // (in this order). // In report mode no hit other than in the main column is possible. - if MainColumnHit or not (toReportMode in FOptions.FMiscOptions) then + if MainColumnHit or not (toReportMode in FOptions.MiscOptions) then begin if MainColumnHit and (Offset < lOffsets[ofsStateImage]) then begin @@ -19079,7 +19147,7 @@ begin // If columns are not used or the main column is hit then the tree indentation must be considered too. if MainColumnHit then begin - if toFixedIndent in FOptions.FPaintOptions then + if toFixedIndent in FOptions.PaintOptions then Dec(Right, FIndent) else begin @@ -19089,7 +19157,7 @@ begin Dec(Right, FIndent); Run := Run.Parent; end; - if toShowRoot in FOptions.FPaintOptions then + if toShowRoot in FOptions.PaintOptions then Dec(Right, FIndent); end; end; @@ -19098,7 +19166,7 @@ begin begin // Position is to the right of calculated indentation which can only happen for the main column. // Check whether it corresponds to a button/checkbox. - if (toShowButtons in FOptions.FPaintOptions) and (vsHasChildren in HitInfo.HitNode.States) then + if (toShowButtons in FOptions.PaintOptions) and (vsHasChildren in HitInfo.HitNode.States) then begin // Position of button is interpreted very generously to avoid forcing the user // to click exactly into the 9x9 pixels area. The entire node height and one full @@ -19124,12 +19192,12 @@ begin // (in this order). // In report mode no hit other than in the main column is possible. - if MainColumnHit or not (toReportMode in FOptions.FMiscOptions) then + if MainColumnHit or not (toReportMode in FOptions.MiscOptions) then begin ImageOffset := Right - FMargin; // Check support is only available for the main column. - if MainColumnHit and (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages) and + if MainColumnHit and (toCheckSupport in FOptions.MiscOptions) and Assigned(FCheckImages) and (HitInfo.HitNode.CheckType <> ctNone) then Dec(ImageOffset, FCheckImages.Width + FImagesMargin); @@ -19214,7 +19282,7 @@ var begin Result := 0; - if toShowRoot in FOptions.FPaintOptions then + if toShowRoot in FOptions.PaintOptions then X := 1 else X := 0; @@ -19234,10 +19302,10 @@ begin Indent := X - 1; // Only use lines if requested. - if (toShowTreeLines in FOptions.FPaintOptions) and - (not (toHideTreeLinesIfThemed in FOptions.FPaintOptions) or not (tsUseThemes in FStates)) then + if (toShowTreeLines in FOptions.PaintOptions) and + (not (toHideTreeLinesIfThemed in FOptions.PaintOptions) or not (tsUseThemes in FStates)) then begin - if toChildrenAbove in FOptions.FPaintOptions then + if toChildrenAbove in FOptions.PaintOptions then begin Dec(X); if not HasVisiblePreviousSibling(Node) then @@ -19294,8 +19362,8 @@ begin end; // Prepare root level. Run points at this stage to a top level node. - if (toShowRoot in FOptions.FPaintOptions) and ((toShowTreeLines in FOptions.FPaintOptions) and - (not (toHideTreeLinesIfThemed in FOptions.FPaintOptions) or not (tsUseThemes in FStates))) then + if (toShowRoot in FOptions.PaintOptions) and ((toShowTreeLines in FOptions.PaintOptions) and + (not (toHideTreeLinesIfThemed in FOptions.PaintOptions) or not (tsUseThemes in FStates))) then begin // Is the top node a root node? if Run = Node then @@ -19327,7 +19395,7 @@ begin end; if (tsUseExplorerTheme in FStates) and HasChildren[Node] and (Indent >= 0) - and not ((vsAllChildrenHidden in Node.States) and (toAutoHideButtons in TreeOptions.FAutoOptions)) then + and not ((vsAllChildrenHidden in Node.States) and (toAutoHideButtons in TreeOptions.AutoOptions)) then LineImage[Indent] := ltNone; end; @@ -19637,7 +19705,7 @@ function TBaseVirtualTree.DoChecking(Node: PVirtualNode; var NewCheckState: TChe // Determines if a node is allowed to change its check state to NewCheckState. begin - if (toReadOnly in FOptions.FMiscOptions) or (vsDisabled in Node.States) then + if (toReadOnly in FOptions.MiscOptions) or (vsDisabled in Node.States) then Result := False else begin @@ -19731,7 +19799,7 @@ begin begin // Invalidate client area from the current column all to the right (or left in RTL mode). R := ClientRect; - if not (toAutoSpanColumns in FOptions.FAutoOptions) then + if not (toAutoSpanColumns in FOptions.AutoOptions) then if UseRightToLeftAlignment then R.Right := FHeader.Columns[Column].Left + FHeader.Columns[Column].Width + ComputeRTLOffset else @@ -19964,7 +20032,7 @@ begin StopTimer(EditTimer); DoStateChange([], [tsEditPending]); if Assigned(FFocusedNode) and not (vsDisabled in FFocusedNode.States) and - not (toReadOnly in FOptions.FMiscOptions) and (FEditLink = nil) then + not (toReadOnly in FOptions.MiscOptions) and (FEditLink = nil) then begin ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions, not (toDisableAutoscrollOnEdit in FOptions.AutoOptions)); FEditLink := DoCreateEditor(FFocusedNode, FEditColumn); @@ -20108,7 +20176,7 @@ begin begin // Do automatic collapsing of last focused node if enabled. This is however only done if // old and new focused node have a common parent node. - if (toAutoExpand in FOptions.FAutoOptions) and Assigned(Node) and (Node.Parent = FFocusedNode.Parent) and + if (toAutoExpand in FOptions.AutoOptions) and Assigned(Node) and (Node.Parent = FFocusedNode.Parent) and (vsExpanded in FFocusedNode.States) then ToggleNode(FFocusedNode) else @@ -20121,13 +20189,13 @@ begin if Assigned(FFocusedNode) then begin // Make sure a valid column is set if columns are used and no column has currently the focus. - if FHeader.UseColumns and (not FHeader.FColumns.IsValidColumn(FFocusedColumn)) then + if FHeader.UseColumns and (not FHeader.Columns.IsValidColumn(FFocusedColumn)) then FFocusedColumn := FHeader.MainColumn; // Do automatic expansion of the newly focused node if enabled. - if (toAutoExpand in FOptions.FAutoOptions) and not (vsExpanded in FFocusedNode.States) then + if (toAutoExpand in FOptions.AutoOptions) and not (vsExpanded in FFocusedNode.States) then ToggleNode(FFocusedNode); InvalidateNode(FFocusedNode); - if (FUpdateCount = 0) and not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions) then + if (FUpdateCount = 0) and not (toDisableAutoscrollOnFocus in FOptions.AutoOptions) then ScrollIntoView(FFocusedNode, (toCenterScrollIntoView in FOptions.SelectionOptions) and (MouseButtonDown * FStates = []), not (toFullRowSelect in FOptions.SelectionOptions) ); end; @@ -20814,7 +20882,7 @@ begin if (suoScrollClientArea in Options) and not (tsToggling in FStates) then begin // Have to invalidate the entire window if there's a background. - if (toShowBackground in FOptions.FPaintOptions) and Assigned(FBackground.Graphic) then + if (toShowBackground in FOptions.PaintOptions) and Assigned(FBackground.Graphic) then begin // Since we don't use ScrollWindow here we have to move all client windows ourselves. DWPStructure := BeginDeferWindowPos(ControlCount); @@ -20855,7 +20923,7 @@ begin if DeltaX <> 0 then begin UpdateHorizontalScrollBar(suoRepaintScrollBars in Options); - if (suoRepaintHeader in Options) and (hoVisible in FHeader.FOptions) then + if (suoRepaintHeader in Options) and (hoVisible in FHeader.Options) then FHeader.Invalidate(nil); if not (tsSizing in FStates) and (FScrollBarOptions.ScrollBars in [System.UITypes.TScrollStyle.ssHorizontal, System.UITypes.TScrollStyle.ssBoth]) then UpdateVerticalScrollBar(suoRepaintScrollBars in Options); @@ -20985,9 +21053,9 @@ begin DeltaY := FLastClickPos.Y - ClientP.Y - 8 else if InRect then - DeltaY := Min(FScrollBarOptions.FIncrementY, ClientHeight) + DeltaY := Min(FScrollBarOptions.VerticalIncrement, ClientHeight) else - DeltaY := Min(FScrollBarOptions.FIncrementY, ClientHeight) * Abs(R.Top - P.Y); + DeltaY := Min(FScrollBarOptions.VerticalIncrement, ClientHeight) * Abs(R.Top - P.Y); if FOffsetY = 0 then Exclude(FScrollDirections, sdUp); end; @@ -20998,9 +21066,9 @@ begin DeltaY := FLastClickPos.Y - ClientP.Y + 8 else if InRect then - DeltaY := -Min(FScrollBarOptions.FIncrementY, ClientHeight) + DeltaY := -Min(FScrollBarOptions.VerticalIncrement, ClientHeight) else - DeltaY := -Min(FScrollBarOptions.FIncrementY, ClientHeight) * Abs(P.Y - R.Bottom); + DeltaY := -Min(FScrollBarOptions.VerticalIncrement, ClientHeight) * Abs(P.Y - R.Bottom); if (ClientHeight - FOffsetY) = Integer(FRangeY) then Exclude(FScrollDirections, sdDown); end; @@ -21011,9 +21079,9 @@ begin DeltaX := FLastClickPos.X - ClientP.X - 8 else if InRect then - DeltaX := FScrollBarOptions.FIncrementX + DeltaX := FScrollBarOptions.HorizontalIncrement else - DeltaX := FScrollBarOptions.FIncrementX * Abs(R.Left - P.X); + DeltaX := FScrollBarOptions.HorizontalIncrement * Abs(R.Left - P.X); if FEffectiveOffsetX = 0 then Exclude(FScrollDirections, sdleft); end; @@ -21024,9 +21092,9 @@ begin DeltaX := FLastClickPos.X - ClientP.X + 8 else if InRect then - DeltaX := -FScrollBarOptions.FIncrementX + DeltaX := -FScrollBarOptions.HorizontalIncrement else - DeltaX := -FScrollBarOptions.FIncrementX * Abs(P.X - R.Right); + DeltaX := -FScrollBarOptions.HorizontalIncrement * Abs(P.X - R.Right); if (ClientWidth + FEffectiveOffsetX) = Integer(FRangeX) then Exclude(FScrollDirections, sdRight); @@ -21186,7 +21254,7 @@ begin // In variable node height mode it might have happend that some or all of the nodes have been adjusted in their // height. During validation updates of the scrollbars is disabled so let's do this here. - if Result and (toVariableNodeHeight in FOptions.FMiscOptions) then + if Result and (toVariableNodeHeight in FOptions.MiscOptions) then begin TThread.Queue(nil, procedure begin UpdateScrollBars(True) end); end; @@ -21323,7 +21391,7 @@ begin FDropTargetNode := HitInfo.HitNode; R := GetDisplayRect(HitInfo.HitNode, FHeader.MainColumn, False); if (hiOnItemLabel in HitInfo.HitPositions) or ((hiOnItem in HitInfo.HitPositions) and - ((toFullRowDrag in FOptions.FMiscOptions) or (toFullRowSelect in FOptions.FSelectionOptions)))then + ((toFullRowDrag in FOptions.MiscOptions) or (toFullRowSelect in FOptions.SelectionOptions)))then FLastDropMode := dmOnNode else if ((R.Top + R.Bottom) div 2) > Pt.Y then @@ -21444,25 +21512,25 @@ begin // Determine amount to scroll. if sdUp in FScrollDirections then begin - DeltaY := Min(FScrollBarOptions.FIncrementY, ClientHeight); + DeltaY := Min(FScrollBarOptions.VerticalIncrement, ClientHeight); if FOffsetY = 0 then Exclude(FScrollDirections, sdUp); end; if sdDown in FScrollDirections then begin - DeltaY := -Min(FScrollBarOptions.FIncrementY, ClientHeight); + DeltaY := -Min(FScrollBarOptions.VerticalIncrement, ClientHeight); if (ClientHeight - FOffsetY) = Integer(FRangeY) then Exclude(FScrollDirections, sdDown); end; if sdLeft in FScrollDirections then begin - DeltaX := FScrollBarOptions.FIncrementX; + DeltaX := FScrollBarOptions.HorizontalIncrement; if FEffectiveOffsetX = 0 then Exclude(FScrollDirections, sdleft); end; if sdRight in FScrollDirections then begin - DeltaX := -FScrollBarOptions.FIncrementX; + DeltaX := -FScrollBarOptions.HorizontalIncrement; if (ClientWidth + FEffectiveOffsetX) = Integer(FRangeX) then Exclude(FScrollDirections, sdRight); end; @@ -21553,7 +21621,7 @@ begin end; // Start auto expand timer if necessary. - if (toAutoDropExpand in FOptions.FAutoOptions) and Assigned(FDropTargetNode) and + if (toAutoDropExpand in FOptions.AutoOptions) and Assigned(FDropTargetNode) and (vsHasChildren in FDropTargetNode.States) then SetTimer(Handle, ExpandTimer, FAutoExpandDelay, nil); end @@ -21628,7 +21696,7 @@ begin begin if UseSelectedBkColor then begin - if Focused or (toPopupMode in FOptions.FPaintOptions) then + if Focused or (toPopupMode in FOptions.PaintOptions) then Brush.Color := FColors.FocusedSelectionColor else Brush.Color := FColors.UnfocusedSelectionColor; @@ -22112,13 +22180,13 @@ begin Include(CheckPositions, hiOnItemButtonExact); if (CheckPositions * HitInfo.HitPositions = []) and - (not (toFullRowSelect in FOptions.FSelectionOptions) or (hiNowhere in HitInfo.HitPositions)) then + (not (toFullRowSelect in FOptions.SelectionOptions) or (hiNowhere in HitInfo.HitPositions)) then FCurrentHotNode := nil else FCurrentHotNode := HitInfo.HitNode; if (FCurrentHotNode <> oldHotNode) or (HitInfo.HitColumn <> FCurrentHotColumn) then begin - DoInvalidate := (toHotTrack in FOptions.PaintOptions) or (toCheckSupport in FOptions.FMiscOptions) or (oldHotNode <> FCurrentHotNode); + DoInvalidate := (toHotTrack in FOptions.PaintOptions) or (toCheckSupport in FOptions.MiscOptions) or (oldHotNode <> FCurrentHotNode); DoHotChange(oldHotNode, HitInfo.HitNode); if Assigned(oldHotNode) and DoInvalidate then InvalidateNode(oldHotNode); @@ -22411,7 +22479,7 @@ var MayEdit: Boolean; begin - MayEdit := not (tsEditing in FStates) and (toEditOnDblClick in FOptions.FMiscOptions); + MayEdit := not (tsEditing in FStates) and (toEditOnDblClick in FOptions.MiscOptions); if tsEditPending in FStates then begin StopTimer(EditTimer); @@ -22420,7 +22488,7 @@ begin if not (tsEditing in FStates) or DoEndEdit then begin - if HitInfo.HitColumn = FHeader.FColumns.FClickIndex then + if HitInfo.HitColumn = FHeader.Columns.FClickIndex then DoColumnDblClick(HitInfo.HitColumn, KeysToShiftState(Message.Keys)); if HitInfo.HitNode <> nil then @@ -22428,7 +22496,7 @@ begin Node := nil; if (hiOnItem in HitInfo.HitPositions) and (HitInfo.HitColumn > NoColumn) and - (coFixed in FHeader.FColumns[HitInfo.HitColumn].FOptions) then + (coFixed in FHeader.Columns[HitInfo.HitColumn].Options) then begin if hiUpperSplitter in HitInfo.HitPositions then Node := GetPreviousVisible(HitInfo.HitNode, True) @@ -22437,7 +22505,7 @@ begin Node := HitInfo.HitNode; end; - if Assigned(Node) and (Node <> FRoot) and (toNodeHeightDblClickResize in FOptions.FMiscOptions) then + if Assigned(Node) and (Node <> FRoot) and (toNodeHeightDblClickResize in FOptions.MiscOptions) then begin if DoNodeHeightDblClickResize(Node, HitInfo.HitColumn, KeysToShiftState(Message.Keys), Point(Message.XPos, Message.YPos)) then begin @@ -22461,10 +22529,10 @@ begin end else begin - if toToggleOnDblClick in FOptions.FMiscOptions then + if toToggleOnDblClick in FOptions.MiscOptions then begin if ((([hiOnItemButton, hiOnItemLabel, hiOnNormalIcon, hiOnStateIcon] * HitInfo.HitPositions) <> []) or - ((toFullRowSelect in FOptions.FSelectionOptions) and Assigned(HitInfo.HitNode))) then + ((toFullRowSelect in FOptions.SelectionOptions) and Assigned(HitInfo.HitNode))) then begin ToggleNode(HitInfo.HitNode); MayEdit := False; @@ -22536,7 +22604,7 @@ var NextColumn: Integer; Dummy: TColumnIndex; begin - if (not FHeader.UseColumns) or (not (toAutoSpanColumns in FOptions.FAutoOptions)) + if (not FHeader.UseColumns) or (not (toAutoSpanColumns in FOptions.AutoOptions)) or (acolumn = FHeader.MainColumn) then begin //no need to find auto spanned next columns @@ -22544,7 +22612,7 @@ var exit; end; //invalidate auto spanned columns too - with FHeader.FColumns do //standard loop for auto span + with FHeader.Columns do //standard loop for auto span begin NextColumn := acolumn; repeat @@ -22594,15 +22662,15 @@ begin end; // Keep clicked column in case the application needs it. - FHeader.FColumns.FClickIndex := HitInfo.HitColumn; + FHeader.Columns.FClickIndex := HitInfo.HitColumn; // Change column only if we have hit the node label. if (hiOnItemLabel in HitInfo.HitPositions) or - (toFullRowSelect in FOptions.FSelectionOptions) or - (toGridExtensions in FOptions.FMiscOptions) then + (toFullRowSelect in FOptions.SelectionOptions) or + (toGridExtensions in FOptions.MiscOptions) then begin NewColumn := FFocusedColumn <> HitInfo.HitColumn; - if toExtendedFocus in FOptions.FSelectionOptions then + if toExtendedFocus in FOptions.SelectionOptions then Column := HitInfo.HitColumn else Column := FHeader.MainColumn; @@ -22635,31 +22703,31 @@ begin // Various combinations determine what states the tree enters now. // We initialize shorthand variables to avoid the following expressions getting too large // and to avoid repeative expensive checks. - IsLabelHit := not AltPressed and not (toSimpleDrawSelection in FOptions.FSelectionOptions) and + IsLabelHit := not AltPressed and not (toSimpleDrawSelection in FOptions.SelectionOptions) and ((hiOnItemLabel in HitInfo.HitPositions) or (hiOnNormalIcon in HitInfo.HitPositions)); IsCellHit := not AltPressed and not IsLabelHit and Assigned(HitInfo.HitNode) and ([hiOnItemButton, hiOnItemCheckBox, hiNoWhere] * HitInfo.HitPositions = []) and - ((toFullRowSelect in FOptions.FSelectionOptions) or - ((toGridExtensions in FOptions.FMiscOptions) and (HitInfo.HitColumn > NoColumn))); + ((toFullRowSelect in FOptions.SelectionOptions) or + ((toGridExtensions in FOptions.MiscOptions) and (HitInfo.HitColumn > NoColumn))); IsAnyHit := IsLabelHit or IsCellHit; - MultiSelect := toMultiSelect in FOptions.FSelectionOptions; + MultiSelect := toMultiSelect in FOptions.SelectionOptions; ShiftEmpty := ShiftState = []; NodeSelected := IsAnyHit and (vsSelected in HitInfo.HitNode.States); // Determine the Drag behavior. - if MultiSelect and not (toDisableDrawSelection in FOptions.FSelectionOptions) then + if MultiSelect and not (toDisableDrawSelection in FOptions.SelectionOptions) then begin // We have MultiSelect and want to draw a selection rectangle. // We will start a full row drag only in case a label was hit, // otherwise a multi selection will start. - FullRowDrag := (toFullRowDrag in FOptions.FMiscOptions) and IsCellHit and + FullRowDrag := (toFullRowDrag in FOptions.MiscOptions) and IsCellHit and not (hiNowhere in HitInfo.HitPositions) and (NodeSelected or (hiOnItemLabel in HitInfo.HitPositions) or (hiOnNormalIcon in HitInfo.HitPositions)); end else // No MultiSelect, hence we can start a drag anywhere in the row. - FullRowDrag := toFullRowDrag in FOptions.FMiscOptions; + FullRowDrag := toFullRowDrag in FOptions.MiscOptions; IsHeightTracking := (Message.Msg = WM_LBUTTONDOWN) and (hiOnItem in HitInfo.HitPositions) and @@ -22726,7 +22794,7 @@ begin DoStateChange([tsClearPending]); // User starts a selection with a selection rectangle. - if not (toDisableDrawSelection in FOptions.FSelectionOptions) and not (IsLabelHit or FullRowDrag) and MultiSelect then + if not (toDisableDrawSelection in FOptions.SelectionOptions) and not (IsLabelHit or FullRowDrag) and MultiSelect then begin SetCapture(Handle); DoStateChange([tsDrawSelPending]); @@ -22770,13 +22838,13 @@ begin // pending node edit if Focused and - ((hiOnItemLabel in HitInfo.HitPositions) or ((toGridExtensions in FOptions.FMiscOptions) and + ((hiOnItemLabel in HitInfo.HitPositions) or ((toGridExtensions in FOptions.MiscOptions) and (hiOnItem in HitInfo.HitPositions))) and NodeSelected and not NewColumn and ShiftEmpty and (SelectedCount = 1) then begin DoStateChange([tsEditPending]); end; - if not (toDisableDrawSelection in FOptions.FSelectionOptions) + if not (toDisableDrawSelection in FOptions.SelectionOptions) and not (IsLabelHit or FullRowDrag) and (MultiSelect or (hiNowhere in HitInfo.HitPositions)) then begin // The original code here was moved up to fix issue #187. @@ -22833,7 +22901,7 @@ begin if NewNode or NewColumn then begin ScrollIntoView(FFocusedNode, False, - not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions) + not (toDisableAutoscrollOnFocus in FOptions.AutoOptions) and not (toFullRowSelect in FOptions.SelectionOptions)); DoFocusChange(FFocusedNode, FFocusedColumn); @@ -22893,7 +22961,7 @@ begin tsScrollPending, tsScrolling]); StopTimer(ScrollTimer); - if (FHeader.FColumns.FClickIndex > NoColumn) and (FHeader.FColumns.FClickIndex = HitInfo.HitColumn) then + if (FHeader.Columns.FClickIndex > NoColumn) and (FHeader.Columns.FClickIndex = HitInfo.HitColumn) then DoColumnClick(HitInfo.HitColumn, KeysToShiftState(Message.Keys)); if FLastHitInfo.HitNode <> nil then begin // Use THitInfo of mouse down here, see issue #692 @@ -22909,7 +22977,7 @@ begin begin // Is the mouse still over the same node? if (HitInfo.HitNode = FFocusedNode) and (hiOnItem in HitInfo.HitPositions) and - (toEditOnClick in FOptions.FMiscOptions) and (FFocusedColumn = HitInfo.HitColumn) and + (toEditOnClick in FOptions.MiscOptions) and (FFocusedColumn = HitInfo.HitColumn) and CanEdit(FFocusedNode, HitInfo.HitColumn) then begin FEditColumn := FFocusedColumn; @@ -23003,7 +23071,7 @@ begin // Fix: Any parent check state must be propagated here. // Because the CheckType is normally set in DoInitNode // by the App. - if (Node.CheckType = ctTriStateCheckBox) and (toAutoTristateTracking in FOptions.FAutoOptions) then + if (Node.CheckType = ctTriStateCheckBox) and (toAutoTristateTracking in FOptions.AutoOptions) then begin ParentCheckState := Self.GetCheckState(Node.Parent); SelfCheckState := Self.GetCheckState(Node); @@ -23032,7 +23100,7 @@ begin Include(States, vsFiltered); - if not (toShowFilteredNodes in FOptions.FPaintOptions) and MustAdjustInternalVariables then + if not (toShowFilteredNodes in FOptions.PaintOptions) and MustAdjustInternalVariables then begin AdjustTotalHeight(Node, -NodeHeight, True); if FullyVisible[Node] then @@ -23109,7 +23177,7 @@ begin else Stop := Node.NextSibling; - if toMultiSelect in FOptions.FSelectionOptions then + if toMultiSelect in FOptions.SelectionOptions then begin // Add all nodes which were selected before to the current selection (unless they are already there). while Node <> Stop do @@ -23171,17 +23239,17 @@ begin begin //Fix: For already selected node when selected, this path //is used that didn't contain the Constraint logic. Added. - Constrained := toLevelSelectConstraint in FOptions.FSelectionOptions; + Constrained := toLevelSelectConstraint in FOptions.SelectionOptions; if Constrained and (FLastSelectionLevel = -1) then FLastSelectionLevel := GetNodeLevelForSelectConstraint(NewItems[0]); AddedNodesSize := NewLength; end else begin - Constrained := toLevelSelectConstraint in FOptions.FSelectionOptions; + Constrained := toLevelSelectConstraint in FOptions.SelectionOptions; if Constrained and (FLastSelectionLevel = -1) then FLastSelectionLevel := GetNodeLevelForSelectConstraint(NewItems[0]); - SiblingConstrained := toSiblingSelectConstraint in FOptions.FSelectionOptions; + SiblingConstrained := toSiblingSelectConstraint in FOptions.SelectionOptions; if SiblingConstrained and (FRangeAnchor = nil) then FRangeAnchor := NewItems[0]; @@ -23578,7 +23646,7 @@ begin Node.CheckState := csUncheckedNormal; // Avoid using SetCheckState() as it handles toSyncCheckboxesWithSelection as well. Inc(PAnsiChar(FSelection[Index])); DoRemoveFromSelection(Node); - AdviseChangeEvent(False, Node, crIgnore); + Change(Node); // Calling Change() here fixes issue #1047 end; end; @@ -23630,7 +23698,7 @@ begin inherited; // Call RegisterDragDrop after all visual inheritance changes to MiscOptions have been applied. - if not (csDesigning in ComponentState) and (toAcceptOLEDrop in FOptions.FMiscOptions) then + if not (csDesigning in ComponentState) and (toAcceptOLEDrop in FOptions.MiscOptions) then if HandleAllocated then RegisterDragDrop(Handle, DragManager as IDropTarget); @@ -23639,15 +23707,15 @@ begin if (tsNeedRootCountUpdate in FStates) and (FRoot.ChildCount > 0) then begin DoStateChange([], [tsNeedRootCountUpdate]); - IsReadOnly := toReadOnly in FOptions.FMiscOptions; - Exclude(FOptions.FMiscOptions, toReadOnly); + IsReadOnly := toReadOnly in FOptions.MiscOptions; + FOptions.InternalSetMiscOptions(FOptions.MiscOptions - [toReadOnly]); LastRootCount := FRoot.ChildCount; FRoot.ChildCount := 0; BeginUpdate; SetChildCount(FRoot, LastRootCount); EndUpdate; if IsReadOnly then - Include(FOptions.FMiscOptions, toReadOnly); + FOptions.InternalSetMiscOptions(FOptions.MiscOptions + [toReadOnly]); end; // Prevent the object inspector at design time from marking the header as being modified @@ -23655,17 +23723,17 @@ begin Updating; try FHeader.UpdateMainColumn; - FHeader.FColumns.FixPositions; - if toAutoBidiColumnOrdering in FOptions.FAutoOptions then - FHeader.FColumns.ReorderColumns(UseRightToLeftAlignment); + FHeader.Columns.FixPositions; + if toAutoBidiColumnOrdering in FOptions.AutoOptions then + FHeader.Columns.ReorderColumns(UseRightToLeftAlignment); // Because of the special recursion and update stopper when creating the window (or resizing it) // we have to manually trigger the auto size calculation here. - if hsNeedScaling in FHeader.FStates then + if hsNeedScaling in FHeader.States then FHeader.RescaleHeader else FHeader.RecalculateHeader; - if hoAutoResize in FHeader.FOptions then - FHeader.FColumns.AdjustAutoSize(InvalidColumn, True); + if hoAutoResize in FHeader.Options then + FHeader.Columns.AdjustAutoSize(InvalidColumn, True); finally Updated; end; @@ -23841,7 +23909,7 @@ begin // Check for components linked to the header. if Assigned(FHeader) then begin - if AComponent = FHeader.FImages then + if AComponent = FHeader.Images then FHeader.Images := nil else if AComponent = FHeader.PopupMenu then @@ -24065,7 +24133,7 @@ begin begin if Selected and not Ghosted then begin - if Focused or (toPopupMode in FOptions.FPaintOptions) then + if Focused or (toPopupMode in FOptions.PaintOptions) then ForegroundColor := ColorToRGB(FColors.FocusedSelectionColor) else ForegroundColor := ColorToRGB(FColors.UnfocusedSelectionColor); @@ -24095,7 +24163,7 @@ begin with PaintInfo do begin CutNode := (vsCutOrCopy in Node.States) and (tsCutPending in FStates); - PaintFocused := Focused or (toGhostedIfUnfocused in FOptions.FPaintOptions); + PaintFocused := Focused or (toGhostedIfUnfocused in FOptions.PaintOptions); // Since the overlay image must be specified together with the image to draw // it is meaningfull to retrieve it in advance. @@ -24109,7 +24177,7 @@ begin begin if (vsSelected in Node.States) and not(Ghosted or CutNode) then begin - if PaintFocused or (toPopupMode in FOptions.FPaintOptions) then + if PaintFocused or (toPopupMode in FOptions.PaintOptions) then Images.BlendColor := FColors.FocusedSelectionColor else Images.BlendColor := FColors.UnfocusedSelectionColor; @@ -24130,13 +24198,13 @@ begin CustomOverlayDrawing := False; // Blend image if enabled and the tree has the focus (or ghosted images must be drawn also if unfocused) ... - if (toUseBlendedImages in FOptions.FPaintOptions) and PaintFocused + if (toUseBlendedImages in FOptions.PaintOptions) and PaintFocused // ... and the image is ghosted... and (Ghosted or // ... or it is not the check image and the node is selected (but selection is not for the entire row)... ((vsSelected in Node.States) and - not (toFullRowSelect in FOptions.FSelectionOptions) and - not (toGridExtensions in FOptions.FMiscOptions)) or + not (toFullRowSelect in FOptions.SelectionOptions) and + not (toGridExtensions in FOptions.MiscOptions)) or // ... or the node must be shown in cut mode. CutNode) then ExtraStyle := ExtraStyle or ILD_BLEND50; @@ -24419,7 +24487,7 @@ const begin // if the full row selection is disabled or toGridExtensions is in the MiscOptions, draw the selection // into the InnerRect, otherwise into the RowRect - if not (toFullRowSelect in FOptions.FSelectionOptions) or (toGridExtensions in FOptions.FMiscOptions) then + if not (toFullRowSelect in FOptions.SelectionOptions) or (toGridExtensions in FOptions.MiscOptions) then DrawThemeBackground(Theme, PaintInfo.Canvas.Handle, TVP_TREEITEM, State, InnerRect, nil) else DrawThemeBackground(Theme, PaintInfo.Canvas.Handle, TVP_TREEITEM, State, RowRect, nil); @@ -24430,7 +24498,7 @@ const Theme: HTHEME; begin Theme := OpenThemeData(Application.ActiveFormHandle, 'Explorer::ItemsView'); - if not (toFullRowSelect in FOptions.FSelectionOptions) or (toGridExtensions in FOptions.FMiscOptions) then + if not (toFullRowSelect in FOptions.SelectionOptions) or (toGridExtensions in FOptions.MiscOptions) then DrawThemeBackground(Theme, PaintInfo.Canvas.Handle, LVP_LISTDETAIL, State, InnerRect, nil) else DrawThemeBackground(Theme, PaintInfo.Canvas.Handle, LVP_LISTDETAIL, State, RowRect, nil); @@ -24453,7 +24521,7 @@ begin with PaintInfo, Canvas do begin // Fill cell background if its color differs from tree background. - with FHeader.FColumns do + with FHeader.Columns do if poColumnColor in PaintOptions then begin Brush.Color := Items[Column].GetEffectiveColor; @@ -24466,7 +24534,7 @@ begin InnerRect := ContentRect; // The selection rectangle depends on alignment. - if not (toGridExtensions in FOptions.FMiscOptions) then + if not (toGridExtensions in FOptions.MiscOptions) then begin case Alignment of taLeftJustify: @@ -24487,7 +24555,7 @@ begin end; end; - if (Column = FFocusedColumn) or (toFullRowSelect in FOptions.FSelectionOptions) then + if (Column = FFocusedColumn) or (toFullRowSelect in FOptions.SelectionOptions) then begin // Fill the selection rectangle. if poDrawSelection in PaintOptions then @@ -24499,8 +24567,8 @@ begin Brush.Color := FColors.DropTargetColor; Pen.Color := FColors.DropTargetBorderColor; - if (toGridExtensions in FOptions.FMiscOptions) or - (toFullRowSelect in FOptions.FSelectionOptions) then + if (toGridExtensions in FOptions.MiscOptions) or + (toFullRowSelect in FOptions.SelectionOptions) then InnerRect := CellRect; if not IsRectEmpty(InnerRect) then if tsUseExplorerTheme in FStates then @@ -24520,7 +24588,7 @@ begin else if vsSelected in Node.States then begin - if Focused or (toPopupMode in FOptions.FPaintOptions) then + if Focused or (toPopupMode in FOptions.PaintOptions) then begin Brush.Color := FColors.FocusedSelectionColor; Pen.Color := FColors.FocusedSelectionBorderColor; @@ -24530,14 +24598,14 @@ begin Brush.Color := FColors.UnfocusedSelectionColor; Pen.Color := FColors.UnfocusedSelectionBorderColor; end; - if (toGridExtensions in FOptions.FMiscOptions) or (toFullRowSelect in FOptions.FSelectionOptions) then + if (toGridExtensions in FOptions.MiscOptions) or (toFullRowSelect in FOptions.SelectionOptions) then InnerRect := CellRect; if not IsRectEmpty(InnerRect) then if tsUseExplorerTheme in FStates then begin // If the node is also hot, its background will be drawn later. - if not (toHotTrack in FOptions.FPaintOptions) or (Node <> FCurrentHotNode) or - ((Column <> FCurrentHotColumn) and not (toFullRowSelect in FOptions.FSelectionOptions)) then + if not (toHotTrack in FOptions.PaintOptions) or (Node <> FCurrentHotNode) or + ((Column <> FCurrentHotColumn) and not (toFullRowSelect in FOptions.SelectionOptions)) then DrawBackground(IfThen(Self.Focused, TREIS_SELECTED, TREIS_SELECTEDNOTFOCUS)); end else @@ -24550,19 +24618,19 @@ begin end; end; - if (tsUseExplorerTheme in FStates) and (toHotTrack in FOptions.FPaintOptions) and (Node = FCurrentHotNode) and - ((Column = FCurrentHotColumn) or (toFullRowSelect in FOptions.FSelectionOptions)) then - DrawBackground(IfThen((vsSelected in Node.States) and not (toAlwaysHideSelection in FOptions.FPaintOptions), + if (tsUseExplorerTheme in FStates) and (toHotTrack in FOptions.PaintOptions) and (Node = FCurrentHotNode) and + ((Column = FCurrentHotColumn) or (toFullRowSelect in FOptions.SelectionOptions)) then + DrawBackground(IfThen((vsSelected in Node.States) and not (toAlwaysHideSelection in FOptions.PaintOptions), TREIS_HOTSELECTED, TREIS_HOT)); - if (Column = FFocusedColumn) or (toFullRowSelect in FOptions.FSelectionOptions) then + if (Column = FFocusedColumn) or (toFullRowSelect in FOptions.SelectionOptions) then begin // draw focus rect if (poDrawFocusRect in PaintOptions) and - (Focused or (toPopupMode in FOptions.FPaintOptions)) and (FFocusedNode = Node) and + (Focused or (toPopupMode in FOptions.PaintOptions)) and (FFocusedNode = Node) and ( (Column = FFocusedColumn) or - ((not (toExtendedFocus in FOptions.FSelectionOptions) or IsWinVistaOrAbove) and - (toFullRowSelect in FOptions.FSelectionOptions) and + ((not (toExtendedFocus in FOptions.SelectionOptions) or IsWinVistaOrAbove) and + (toFullRowSelect in FOptions.SelectionOptions) and (tsUseExplorerTheme in FStates) ) ) then begin TextColorBackup := GetTextColor(Handle); @@ -24570,11 +24638,11 @@ begin BackColorBackup := GetBkColor(Handle); SetBkColor(Handle, 0); - if not (toExtendedFocus in FOptions.FSelectionOptions) and (toFullRowSelect in FOptions.FSelectionOptions) and + if not (toExtendedFocus in FOptions.SelectionOptions) and (toFullRowSelect in FOptions.SelectionOptions) and (tsUseExplorerTheme in FStates) then FocusRect := RowRect else - if toGridExtensions in FOptions.FMiscOptions then + if toGridExtensions in FOptions.MiscOptions then FocusRect := CellRect else FocusRect := InnerRect; @@ -25539,10 +25607,10 @@ begin InflateRect(FHeaderRect, -OffsetX, -OffsetY); - if hoVisible in FHeader.FOptions then + if hoVisible in FHeader.Options then begin if FHeaderRect.Left <= FHeaderRect.Right then - FHeaderRect.Bottom := FHeaderRect.Top + Integer(FHeader.FHeight) + FHeaderRect.Bottom := FHeaderRect.Top + Integer(FHeader.Height) else FHeaderRect := Rect(0, 0, 0, 0); end @@ -25574,10 +25642,10 @@ begin end; if vsMultiline in FFocusedNode.States then R := GetDisplayRect(FFocusedNode, FEditColumn, True, False) - else if not (toGridExtensions in FOptions.FMiscOptions) then + else if not (toGridExtensions in FOptions.MiscOptions) then R := GetDisplayRect(FFocusedNode, FEditColumn, True, True); - if (toGridExtensions in FOptions.FMiscOptions) then + if (toGridExtensions in FOptions.MiscOptions) then begin // Use the whole cell when grid extensions are on. R := GetDisplayRect(FFocusedNode, FEditColumn, False, False); @@ -25600,8 +25668,8 @@ begin end else begin - CurrentAlignment := FHeader.Columns[FEditColumn].FAlignment; - CurrentBidiMode := FHeader.Columns[FEditColumn].FBiDiMode; + CurrentAlignment := FHeader.Columns[FEditColumn].Alignment; + CurrentBidiMode := FHeader.Columns[FEditColumn].BiDiMode; end; // Consider bidi mode here. In RTL context does left alignment actually mean right alignment and vice versa. if CurrentBidiMode <> bdLeftToRight then @@ -25777,7 +25845,7 @@ begin Handled := False; // Try the header whether it needs to take this message. - if Assigned(FHeader) and (FHeader.FStates <> []) then + if Assigned(FHeader) and (FHeader.States <> []) then Handled := FHeader.HandleMessage(Message); if not Handled then begin @@ -25891,7 +25959,7 @@ var begin // Initialize the node first if necessary and wanted. - if toInitOnSave in FOptions.FMiscOptions then + if toInitOnSave in FOptions.MiscOptions then begin if not (vsInitialized in Node.States) then InitNode(Node); @@ -25951,7 +26019,7 @@ function TBaseVirtualTree.AddChild(Parent: PVirtualNode; UserData: Pointer = nil // against the virtual paradigm and hence I dissuade from its usage. begin - if not (toReadOnly in FOptions.FMiscOptions) then + if not (toReadOnly in FOptions.MiscOptions) then Result := InsertNode(Parent, TVTNodeAttachMode.amAddChildLast, UserData) else Result := nil; @@ -25983,7 +26051,7 @@ var Node: PVirtualNode; begin - if not (toReadOnly in FOptions.FMiscOptions) then + if not (toReadOnly in FOptions.MiscOptions) then begin // check first whether this is a stream we can read Stream.ReadBuffer(ThisID, SizeOf(TMagicID)); @@ -26041,7 +26109,7 @@ end; procedure TBaseVirtualTree.Assign(Source: TPersistent); begin - if (Source is TBaseVirtualTree) and not (toReadOnly in FOptions.FMiscOptions) then + if (Source is TBaseVirtualTree) and not (toReadOnly in FOptions.MiscOptions) then with Source as TBaseVirtualTree do begin Self.Align := Align; @@ -26265,7 +26333,7 @@ function TBaseVirtualTree.CanEdit(Node: PVirtualNode; Column: TColumnIndex): Boo // Returns True if the given node can be edited. begin - Result := (toEditable in FOptions.FMiscOptions) and Enabled and not (toReadOnly in FOptions.FMiscOptions) + Result := (toEditable in FOptions.MiscOptions) and Enabled and not (toReadOnly in FOptions.MiscOptions) and ((Column < 0) or (coEditable in FHeader.Columns[Column].Options)); DoCanEdit(Node, Column, Result); end; @@ -26292,7 +26360,7 @@ end; procedure TBaseVirtualTree.Clear; begin - if (not IsEmpty and not (toReadOnly in FOptions.FMiscOptions)) or (csDestroying in ComponentState) then + if (not IsEmpty and not (toReadOnly in FOptions.MiscOptions)) or (csDestroying in ComponentState) then begin BeginUpdate; try @@ -26350,6 +26418,13 @@ end; //---------------------------------------------------------------------------------------------------------------------- +procedure TBaseVirtualTree.ClearDragManager; +begin + Pointer(FDragManager) := nil; +end; + +//---------------------------------------------------------------------------------------------------------------------- + procedure TBaseVirtualTree.ClearSelection(pFireChangeEvent: Boolean); var @@ -26436,7 +26511,7 @@ begin else TargetTree := TreeFromNode(Target); - if not (toReadOnly in TargetTree.FOptions.FMiscOptions) then + if not (toReadOnly in TargetTree.TreeOptions.MiscOptions) then begin if Target = TargetTree.FRoot then begin @@ -26527,7 +26602,7 @@ end; procedure TBaseVirtualTree.CutToClipboard; begin - if (FSelectionCount > 0) and not (toReadOnly in FOptions.FMiscOptions) then + if (FSelectionCount > 0) and not (toReadOnly in FOptions.MiscOptions) then begin if OleSetClipboard(TVTDataObject.Create(Self, True)) = S_OK then begin @@ -26553,7 +26628,7 @@ var ParentVisible: Boolean; begin - if Assigned(Node) and (Node.ChildCount > 0) and not (toReadOnly in FOptions.FMiscOptions) then + if Assigned(Node) and (Node.ChildCount > 0) and not (toReadOnly in FOptions.MiscOptions) then begin Assert(not (tsIterating in FStates), 'Deleting nodes during tree iteration leads to invalid pointers.'); @@ -26647,7 +26722,7 @@ var WasInSynchMode: Boolean; begin - if Assigned(Node) and (Node <> FRoot) and not (toReadOnly in FOptions.FMiscOptions) then + if Assigned(Node) and (Node <> FRoot) and not (toReadOnly in FOptions.MiscOptions) then begin Assert(not (tsIterating in FStates), 'Deleting nodes during tree iteration leads to invalid pointers.'); @@ -26757,7 +26832,7 @@ var lNodes: TNodeArray; begin lNodes := nil; - if (FSelectionCount > 0) and not (toReadOnly in FOptions.FMiscOptions) then + if (FSelectionCount > 0) and not (toReadOnly in FOptions.MiscOptions) then begin lNodes := GetSortedSelection(True); DeleteNodes(lNodes); @@ -26787,7 +26862,7 @@ begin Result := tsEditing in FStates; // If the tree is already editing then we don't disrupt this. - if not Result and not (toReadOnly in FOptions.FMiscOptions) then + if not Result and not (toReadOnly in FOptions.MiscOptions) then begin FocusedNode := Node; if Assigned(FFocusedNode) and (Node = FFocusedNode) and CanEdit(FFocusedNode, Column) then @@ -26879,8 +26954,8 @@ begin if tsChangePending in FStates then DoChange(FLastChangedNode); finally - if toAutoSort in FOptions.FAutoOptions then - SortTree(FHeader.FSortColumn, FHeader.FSortDirection, True); + if toAutoSort in FOptions.AutoOptions then + SortTree(FHeader.SortColumn, FHeader.SortDirection, True); SetUpdateState(False); if HandleAllocated then @@ -26918,7 +26993,7 @@ begin if Result then CopyToClipboard else - if not (toReadOnly in FOptions.FMiscOptions) then + if not (toReadOnly in FOptions.MiscOptions) then begin Result := Action is TEditCut; if Result then @@ -27161,7 +27236,7 @@ begin // Limit left and right bounds to the given column (if any) and move bounds according to current scroll state. if Column > NoColumn then begin - FHeader.FColumns.GetColumnBounds(Column, Result.Left, Result.Right); + FHeader.Columns.GetColumnBounds(Column, Result.Left, Result.Right); // The right column border is not part of this cell. Dec(Result.Right); OffsetRect(Result, 0, FOffsetY); @@ -27180,8 +27255,8 @@ begin end else begin - CurrentBidiMode := FHeader.FColumns[Column].BidiMode; - CurrentAlignment := FHeader.FColumns[Column].Alignment; + CurrentBidiMode := FHeader.Columns[Column].BidiMode; + CurrentAlignment := FHeader.Columns[Column].Alignment; end; GetOffsets(Node, lOffsets, TVTElement.ofsLabel, Column); @@ -27265,7 +27340,7 @@ function TBaseVirtualTree.GetEffectivelyFiltered(Node: PVirtualNode): Boolean; begin if Assigned(Node) then - Result := (vsFiltered in Node.States) and not (toShowFilteredNodes in FOptions.FPaintOptions) + Result := (vsFiltered in Node.States) and not (toShowFilteredNodes in FOptions.PaintOptions) else Result := False; end; @@ -27285,7 +27360,7 @@ function TBaseVirtualTree.GetFirst(ConsiderChildrenAbove: Boolean = False): PVir // Returns the first node in the tree while optionally considering toChildrenAbove. begin - if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then + if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then begin if vsHasChildren in FRoot.States then begin @@ -27433,7 +27508,7 @@ function TBaseVirtualTree.GetFirstNoInit(ConsiderChildrenAbove: Boolean = False) // No initialization is performed. begin - if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then + if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then begin if vsHasChildren in FRoot.States then begin @@ -27488,7 +27563,7 @@ begin begin Result := GetFirstChild(Result); - if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then + if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then begin repeat // Search the first visible sibling. @@ -27614,7 +27689,7 @@ begin begin Result := Result.FirstChild; - if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then + if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then begin repeat // Search the first visible sibling. @@ -27737,24 +27812,24 @@ begin begin HitInfo.HitColumn := FHeader.Columns.GetColumnAndBounds(Point(X, Y), ColLeft, ColRight, False); // If auto column spanning is enabled then look for the last non empty column. - if toAutoSpanColumns in FOptions.FAutoOptions then + if toAutoSpanColumns in FOptions.AutoOptions then begin InitialColumn := HitInfo.HitColumn; // Search to the left of the hit column for empty columns. while (HitInfo.HitColumn > NoColumn) and ColumnIsEmpty(HitInfo.HitNode, HitInfo.HitColumn) do begin - NextColumn := FHeader.FColumns.GetPreviousVisibleColumn(HitInfo.HitColumn); + NextColumn := FHeader.Columns.GetPreviousVisibleColumn(HitInfo.HitColumn); if NextColumn = InvalidColumn then Break; HitInfo.HitColumn := NextColumn; - Dec(ColLeft, FHeader.FColumns[NextColumn].Width); + Dec(ColLeft, FHeader.Columns[NextColumn].Width); end; // Search to the right of the hit column for empty columns. repeat - InitialColumn := FHeader.FColumns.GetNextVisibleColumn(InitialColumn); + InitialColumn := FHeader.Columns.GetNextVisibleColumn(InitialColumn); if (InitialColumn = InvalidColumn) or not ColumnIsEmpty(HitInfo.HitNode, InitialColumn) then Break; - Inc(ColRight, FHeader.FColumns[InitialColumn].Width); + Inc(ColRight, FHeader.Columns[InitialColumn].Width); until False; end; // Make the X position and the right border relative to the start of the column. @@ -27776,7 +27851,7 @@ begin HitInfo.HitPositions := [hiOnItem]; // Avoid getting the display rect if this is not necessary. - if toNodeHeightResize in FOptions.FMiscOptions then + if toNodeHeightResize in FOptions.MiscOptions then begin NodeRect := GetDisplayRect(HitInfo.HitNode, HitInfo.HitColumn, False); if Y <= (NodeRect.Top - FOffsetY + 1) then @@ -27793,8 +27868,8 @@ begin end else begin - CurrentBidiMode := FHeader.FColumns[HitInfo.HitColumn].BidiMode; - CurrentAlignment := FHeader.FColumns[HitInfo.HitColumn].Alignment; + CurrentBidiMode := FHeader.Columns[HitInfo.HitColumn].BidiMode; + CurrentAlignment := FHeader.Columns[HitInfo.HitColumn].Alignment; end; if CurrentBidiMode = bdLeftToRight then @@ -27818,7 +27893,7 @@ var begin Result := GetLastChild(Node); - if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.FPaintOptions) then + if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.PaintOptions) then while Assigned(Result) do begin // Test if there is a next last child. If not keep the node from the last run. @@ -27854,7 +27929,7 @@ var begin Result := GetLastChildNoInit(Node); - if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.FPaintOptions) then + if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.PaintOptions) then while Assigned(Result) do begin // Test if there is a next last child. If not keep the node from the last run. @@ -27989,7 +28064,7 @@ var begin Result := GetLastVisibleChildNoInit(Node, IncludeFiltered); - if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.FPaintOptions) then + if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.PaintOptions) then while Assigned(Result) and (vsExpanded in Result.States) do begin // Test if there is a next last child. If not keep the node from the last run. @@ -28024,7 +28099,7 @@ begin if OperationCanceled then begin // Behave non-destructive. - Result := FHeader.FColumns[Column].Width; + Result := FHeader.Columns[Column].Width; Exit; end else @@ -28047,7 +28122,7 @@ begin LastNode := nil; if hoAutoResizeInclCaption in FHeader.Options then - Result := Result + (2 * Header.Columns[Column].FMargin + Header.Columns[Column].CaptionWidth + 2); + Result := Result + (2 * Header.Columns[Column].Margin + Header.Columns[Column].CaptionWidth + 2); while Assigned(Run) and not OperationCanceled do begin @@ -28078,7 +28153,7 @@ begin Break; Run := NextNode; end; - if toShowVertGridLines in FOptions.FPaintOptions then + if toShowVertGridLines in FOptions.PaintOptions then Inc(Result); if Assigned(FOnAfterGetMaxColumnWidth) then @@ -28101,7 +28176,7 @@ begin begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); - if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then + if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then begin // If this node has no siblings use the parent. if not Assigned(Result.NextSibling) then @@ -28314,7 +28389,7 @@ begin begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); - if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then + if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then begin // If this node has no siblings use the parent. if not Assigned(Result.NextSibling) then @@ -28448,7 +28523,7 @@ begin if not FullyVisible[Result] then Result := GetVisibleParent(Result, True); - if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then + if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then begin repeat // If there a no siblings anymore, go up one level. @@ -28560,7 +28635,7 @@ begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); repeat - if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then + if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then begin repeat // If there a no siblings anymore, go up one level. @@ -28867,7 +28942,7 @@ begin begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); - if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then + if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then begin // Has this node got children? Initialize them if necessary. if (vsHasChildren in Result.States) and (Result.ChildCount = 0) then @@ -29073,7 +29148,7 @@ begin begin Assert(Result <> FRoot, 'Node must not be the hidden root node.'); - if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then + if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then begin // If there is a last child, take it; if not try the previous sibling. if Assigned(Result.LastChild) then @@ -29206,7 +29281,7 @@ begin end else begin - if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then + if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then begin repeat if Assigned(Result.LastChild) and (vsExpanded in Result.States) then @@ -29315,7 +29390,7 @@ begin end else begin - if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then + if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then begin repeat // Is the current node expanded and has children? @@ -29845,8 +29920,8 @@ begin // Note: Node can never be FRoot at this point. StructureChange(Result, crNodeAdded); // If auto sort is enabled then sort the node or its parent (depending on the insert mode). - if (toAutoSort in FOptions.FAutoOptions) and (FHeader.FSortColumn > InvalidColumn) then - Sort(Node.Parent, FHeader.FSortColumn, FHeader.FSortDirection, True); + if (toAutoSort in FOptions.AutoOptions) and (FHeader.SortColumn > InvalidColumn) then + Sort(Node.Parent, FHeader.SortColumn, FHeader.SortDirection, True); InvalidateToBottom(Result) end; amAddChildFirst, @@ -29854,8 +29929,8 @@ begin begin StructureChange(Node, crChildAdded); // If auto sort is enabled then sort the node or its parent (depending on the insert mode). - if (toAutoSort in FOptions.FAutoOptions) and (FHeader.FSortColumn > InvalidColumn) then - Sort(Node, FHeader.FSortColumn, FHeader.FSortDirection, True); + if (toAutoSort in FOptions.AutoOptions) and (FHeader.SortColumn > InvalidColumn) then + Sort(Node, FHeader.SortColumn, FHeader.SortDirection, True); InvalidateToBottom(Node); end; end; @@ -29911,7 +29986,7 @@ var R: TRect; begin - if (FUpdateCount = 0) and HandleAllocated and FHeader.FColumns.IsValidColumn(Column) then + if (FUpdateCount = 0) and HandleAllocated and FHeader.Columns.IsValidColumn(Column) then begin R := ClientRect; FHeader.Columns.GetColumnBounds(Column, R.Left, R.Right); @@ -29960,7 +30035,7 @@ begin R := GetDisplayRect(Node, NoColumn, False); if R.Top < ClientHeight then begin - if (toChildrenAbove in FOptions.FPaintOptions) and (vsExpanded in Node.States) then + if (toChildrenAbove in FOptions.PaintOptions) and (vsExpanded in Node.States) then Dec(R.Top, Node.TotalHeight + NodeHeight[Node]); R.Bottom := ClientHeight; InvalidateRect(Handle, @R, False); @@ -29983,7 +30058,7 @@ var TriggerChange: Boolean; begin - if not FSelectionLocked and (toMultiSelect in FOptions.FSelectionOptions) then + if not FSelectionLocked and (toMultiSelect in FOptions.SelectionOptions) then begin Run := FRoot.FirstChild; ClearTempCache; @@ -30182,7 +30257,7 @@ var Node: PVirtualNode; begin - if not (toReadOnly in FOptions.FMiscOptions) then + if not (toReadOnly in FOptions.MiscOptions) then begin Clear; // Check first whether this is a stream we can read. @@ -30239,7 +30314,7 @@ begin if not (vsHeightMeasured in Node.States) then begin Include(Node.States, vsHeightMeasured); - if (toVariableNodeHeight in FOptions.FMiscOptions) then + if (toVariableNodeHeight in FOptions.MiscOptions) then begin NewNodeHeight := Node.NodeHeight; // Anonymous methods help to make this thread safe easily. @@ -30293,7 +30368,7 @@ begin Allowed := (Source <> Target) or ((Mode in [amInsertBefore, amInsertAfter]) and ChildrenOnly); if Allowed and (Mode <> amNoWhere) and Assigned(Source) and (Source <> FRoot) and - not (toReadOnly in FOptions.FMiscOptions) then + not (toReadOnly in FOptions.MiscOptions) then begin // Assume that an empty destination means the root in this (the source) tree. if Target = nil then @@ -30561,16 +30636,16 @@ begin R := Rect(0, 0, Max(FRangeX, ClientWidth), 0); // For quick checks some intermediate variables are used. - UseBackground := (toShowBackground in FOptions.FPaintOptions) and Assigned(FBackground.Graphic) and + UseBackground := (toShowBackground in FOptions.PaintOptions) and Assigned(FBackground.Graphic) and (poBackground in PaintOptions); - ShowCheckImages := Assigned(FCheckImages) and (toCheckSupport in FOptions.FMiscOptions); + ShowCheckImages := Assigned(FCheckImages) and (toCheckSupport in FOptions.MiscOptions); UseColumns := FHeader.UseColumns; // Adjust paint options to tree settings. Hide selection if told so or the tree is unfocused. - if (toAlwaysHideSelection in FOptions.FPaintOptions) or - (not Focused and (toHideSelection in FOptions.FPaintOptions)) then + if (toAlwaysHideSelection in FOptions.PaintOptions) or + (not Focused and (toHideSelection in FOptions.PaintOptions)) then Exclude(PaintOptions, poDrawSelection); - if toHideFocusRect in FOptions.FPaintOptions then + if toHideFocusRect in FOptions.PaintOptions then Exclude(PaintOptions, poDrawFocusRect); // Determine node to start drawing with. @@ -30609,7 +30684,7 @@ begin // Initialize node if not already done. if not (vsInitialized in PaintInfo.Node.States) then InitNode(PaintInfo.Node); - if (vsSelected in PaintInfo.Node.States) and not (toChildrenAbove in FOptions.FPaintOptions) then + if (vsSelected in PaintInfo.Node.States) and not (toChildrenAbove in FOptions.PaintOptions) then Inc(SelectLevel); // Ensure the node's height is determined. @@ -30670,7 +30745,7 @@ begin InitializeFirstColumnValues(PaintInfo); // Now go through all visible columns (there's still one run if columns aren't used). - with FHeader.FColumns do + with FHeader.Columns do begin while ((PaintInfo.Column > InvalidColumn) or not UseColumns) and (PaintInfo.CellRect.Left < Window.Right) do @@ -30680,8 +30755,8 @@ begin PaintInfo.Column := FPositionToIndex[PaintInfo.Position]; if FirstColumn = InvalidColumn then FirstColumn := PaintInfo.Column; - PaintInfo.BidiMode := Items[PaintInfo.Column].FBiDiMode; - PaintInfo.Alignment := Items[PaintInfo.Column].FAlignment; + PaintInfo.BidiMode := Items[PaintInfo.Column].BiDiMode; + PaintInfo.Alignment := Items[PaintInfo.Column].Alignment; end else begin @@ -30698,7 +30773,7 @@ begin ((Column = FEditColumn) or not UseColumns) then Exclude(PaintOptions, poDrawSelection); if not UseColumns or - ((vsSelected in Node.States) and (toFullRowSelect in FOptions.FSelectionOptions) and + ((vsSelected in Node.States) and (toFullRowSelect in FOptions.SelectionOptions) and (poDrawSelection in PaintOptions)) or (coParentColor in Items[PaintInfo.Column].Options) or ((coStyleColor in Items[PaintInfo.Column].Options) and VclStyleEnabled) @@ -30713,7 +30788,7 @@ begin // Paint the current cell if it is marked as being visible or columns aren't used and // if this cell belongs to the main column if only the main column should be drawn. - if (not UseColumns or (coVisible in Items[PaintInfo.Column].FOptions)) and + if (not UseColumns or (coVisible in Items[PaintInfo.Column].Options)) and (not (poMainOnly in PaintOptions) or IsMainColumn) then begin AdjustPaintCellRect(PaintInfo, NextColumn); @@ -30754,19 +30829,19 @@ begin end; // Paint the horizontal grid line. - if (poGridLines in PaintOptions) and (toShowHorzGridLines in FOptions.FPaintOptions) then + if (poGridLines in PaintOptions) and (toShowHorzGridLines in FOptions.PaintOptions) then begin Canvas.Font.Color := FColors.GridLineColor; if IsMainColumn and (FLineMode = lmBands) then begin if BidiMode = bdLeftToRight then begin - DrawDottedHLine(PaintInfo, CellRect.Left + IfThen(toFixedIndent in FOptions.FPaintOptions, 1, IndentSize) * Integer(FIndent), CellRect.Right - 1, + DrawDottedHLine(PaintInfo, CellRect.Left + IfThen(toFixedIndent in FOptions.PaintOptions, 1, IndentSize) * Integer(FIndent), CellRect.Right - 1, CellRect.Bottom - 1); end else begin - DrawDottedHLine(PaintInfo, CellRect.Left, CellRect.Right - IfThen(toFixedIndent in FOptions.FPaintOptions, 1, IndentSize) * Integer(FIndent) - 1, + DrawDottedHLine(PaintInfo, CellRect.Left, CellRect.Right - IfThen(toFixedIndent in FOptions.PaintOptions, 1, IndentSize) * Integer(FIndent) - 1, CellRect.Bottom - 1); end; end @@ -30780,16 +30855,16 @@ begin if UseColumns then begin // Paint vertical grid line. - if (poGridLines in PaintOptions) and (toShowVertGridLines in FOptions.FPaintOptions) then + if (poGridLines in PaintOptions) and (toShowVertGridLines in FOptions.PaintOptions) then begin // These variables and the nested if conditions shall make the logic // easier to understand. CellIsTouchingClientRight := PaintInfo.CellRect.Right = ClientRect.Right; CellIsInLastColumn := Position = TColumnPosition(Count - 1); - ColumnIsFixed := coFixed in FHeader.FColumns[Column].Options; + ColumnIsFixed := coFixed in FHeader.Columns[Column].Options; // Don't draw if this is the last column and the header is in autosize mode. - if not ((hoAutoResize in FHeader.FOptions) and CellIsInLastColumn) then + if not ((hoAutoResize in FHeader.Options) and CellIsInLastColumn) then begin // We have to take spanned cells into account which we determine // by checking if CellRect.Right equals the Window.Right. @@ -30802,7 +30877,7 @@ begin if (BidiMode = bdLeftToRight) or not ColumnIsEmpty(Node, Column) then begin Canvas.Font.Color := FColors.GridLineColor; - lUseSelectedBkColor := (poDrawSelection in PaintOptions) and (toFullRowSelect in FOptions.FSelectionOptions) and + lUseSelectedBkColor := (poDrawSelection in PaintOptions) and (toFullRowSelect in FOptions.SelectionOptions) and (vsSelected in Node.States) and not (toUseBlendedSelection in FOptions.PaintOptions) and not (tsUseExplorerTheme in FStates); DrawDottedVLine(PaintInfo, CellRect.Top, CellRect.Bottom, CellRect.Right - 1, lUseSelectedBkColor); @@ -30821,16 +30896,16 @@ begin // Some parts are only drawn for the main column. if IsMainColumn then begin - if (toShowTreeLines in FOptions.FPaintOptions) and - (not (toHideTreeLinesIfThemed in FOptions.FPaintOptions) or + if (toShowTreeLines in FOptions.PaintOptions) and + (not (toHideTreeLinesIfThemed in FOptions.PaintOptions) or not (tsUseThemes in FStates)) then - PaintTreeLines(PaintInfo, IfThen(toFixedIndent in FOptions.FPaintOptions, 1, + PaintTreeLines(PaintInfo, IfThen(toFixedIndent in FOptions.PaintOptions, 1, IndentSize), LineImage); // Show node button if allowed, if there child nodes and at least one of the child // nodes is visible or auto button hiding is disabled. - if (toShowButtons in FOptions.FPaintOptions) and (vsHasChildren in Node.States) and + if (toShowButtons in FOptions.PaintOptions) and (vsHasChildren in Node.States) and not ((vsAllChildrenHidden in Node.States) and - (toAutoHideButtons in TreeOptions.FAutoOptions)) and + (toAutoHideButtons in TreeOptions.AutoOptions)) and ((toShowRoot in TreeOptions.PaintOptions) or (GetNodeLevel(Node) > 0)) then PaintNodeButton(Canvas, Node, Column, CellRect, Offsets[ofsToggleButton], ButtonY, BidiMode); // Relative X position of toggle button is needed for proper BiDi calculation @@ -30871,7 +30946,7 @@ begin PaintInfo.Position := Items[NextColumn].Position; // Move clip rectangle and continue. - if coVisible in Items[NextColumn].FOptions then + if coVisible in Items[NextColumn].Options then with PaintInfo do begin Items[NextColumn].GetAbsoluteBounds(CellRect.Left, CellRect.Right); @@ -30887,7 +30962,7 @@ begin DoAfterItemPaint(Canvas, Node, R); // Final touch for this node: mark it if it is the current drop target node. - if (Node = FDropTargetNode) and (toShowDropmark in FOptions.FPaintOptions) and + if (Node = FDropTargetNode) and (toShowDropmark in FOptions.PaintOptions) and (poDrawDropMark in PaintOptions) then DoPaintDropMark(Canvas, Node, R); end; @@ -30956,7 +31031,7 @@ begin SetCanvasOrigin(PaintInfo.Canvas, Target.X, 0); // This line caused issue #313 when it was placed above the if-statement if UseColumns then begin - with FHeader.FColumns do + with FHeader.Columns do begin // If there is no content in the tree then the first column has not yet been determined. if FirstColumn = InvalidColumn then @@ -30966,7 +31041,7 @@ begin if FirstColumn <> InvalidColumn then begin R.Left := Items[FirstColumn].Left; - R.Right := R.Left + Items[FirstColumn].FWidth; + R.Right := R.Left + Items[FirstColumn].Width; if R.Right > TargetRect.Left then Break; FirstColumn := GetNextVisibleColumn(FirstColumn); @@ -30976,7 +31051,7 @@ begin else begin R.Left := Items[FirstColumn].Left; - R.Right := R.Left + Items[FirstColumn].FWidth; + R.Right := R.Left + Items[FirstColumn].Width; end; // Initialize MaxRight. @@ -30987,7 +31062,7 @@ begin begin // Determine left and right coordinate of the current column ColLeft := Items[FirstColumn].Left; - ColRight := (ColLeft + Items[FirstColumn].FWidth); + ColRight := (ColLeft + Items[FirstColumn].Width); // Check wether this column needs to be painted at all. if (ColRight >= MaxRight) then @@ -30997,16 +31072,16 @@ begin MaxRight := ColRight; // And record were to start the next column. if (poGridLines in PaintOptions) and - (toFullVertGridLines in FOptions.FPaintOptions) and - (toShowVertGridLines in FOptions.FPaintOptions) and - (not (hoAutoResize in FHeader.FOptions) or (Cardinal(FirstColumn) < TColumnPosition(Count - 1))) then + (toFullVertGridLines in FOptions.PaintOptions) and + (toShowVertGridLines in FOptions.PaintOptions) and + (not (hoAutoResize in FHeader.Options) or (Cardinal(FirstColumn) < TColumnPosition(Count - 1))) then begin DrawDottedVLine(PaintInfo, R.Top, R.Bottom, R.Right - 1); Dec(R.Right); end; - if not (coParentColor in Items[FirstColumn].FOptions) then - PaintInfo.Canvas.Brush.Color := Items[FirstColumn].FColor + if not (coParentColor in Items[FirstColumn].Options) then + PaintInfo.Canvas.Brush.Color := Items[FirstColumn].Color else PaintInfo.Canvas.Brush.Color := FColors.BackGroundColor; PaintInfo.Canvas.FillRect(R); @@ -31021,8 +31096,8 @@ begin R.Right := TargetRect.Right + Target.X; // Prevent erasing the last vertical grid line. if (poGridLines in PaintOptions) and - (toFullVertGridLines in FOptions.FPaintOptions) and (toShowVertGridLines in FOptions.FPaintOptions) and - (not (hoAutoResize in FHeader.FOptions)) then + (toFullVertGridLines in FOptions.PaintOptions) and (toShowVertGridLines in FOptions.PaintOptions) and + (not (hoAutoResize in FHeader.Options)) then Inc(R.Left); PaintInfo.Canvas.Brush.Color := FColors.BackGroundColor; PaintInfo.Canvas.FillRect(R); @@ -31097,7 +31172,7 @@ var begin Result := False; - if not (toReadOnly in FOptions.FMiscOptions) then + if not (toReadOnly in FOptions.MiscOptions) then begin if OleGetClipboard(Data) <> S_OK then ShowError(SClipboardFailed, hcTFClipboardFailed) @@ -31268,7 +31343,7 @@ begin LogFont.lfQuality := ANTIALIASED_QUALITY; FHeader.Font.Handle := CreateFontIndirect(LogFont); ImgRect.Bottom := FHeader.Height; - FHeader.FColumns.PaintHeader(Image.Canvas.Handle, ImgRect, 0); + FHeader.Columns.PaintHeader(Image.Canvas.Handle, ImgRect, 0); FHeader.Font := SaveHeaderFont; finally SaveHeaderFont.Free; @@ -31483,7 +31558,7 @@ begin cfFormat := CF_VIRTUALTREE; end; Result := DataObject.QueryGetData(StandardOLEFormat) = S_OK; - if Result and not (toReadOnly in FOptions.FMiscOptions) then + if Result and not (toReadOnly in FOptions.MiscOptions) then begin BeginUpdate; Result := False; @@ -31773,10 +31848,10 @@ begin Run := Run.Parent; end; UseColumns := FHeader.UseColumns; - if UseColumns and FHeader.FColumns.IsValidColumn(FFocusedColumn) then - R := GetDisplayRect(Node, FFocusedColumn, not (toGridExtensions in FOptions.FMiscOptions)) + if UseColumns and FHeader.Columns.IsValidColumn(FFocusedColumn) then + R := GetDisplayRect(Node, FFocusedColumn, not (toGridExtensions in FOptions.MiscOptions)) else - R := GetDisplayRect(Node, NoColumn, not (toGridExtensions in FOptions.FMiscOptions)); + R := GetDisplayRect(Node, NoColumn, not (toGridExtensions in FOptions.MiscOptions)); // The returned rectangle can never be empty after the expand code above. // 1) scroll vertically @@ -31842,7 +31917,7 @@ begin ColumnRight := ColumnLeft + Header.Columns.Items[Column].Width; end else if Assigned(Node) and (toCenterScrollIntoView in FOptions.SelectionOptions) then begin Center := False; - R := GetDisplayRect(Node, NoColumn, not (toGridExtensions in FOptions.FMiscOptions)); + R := GetDisplayRect(Node, NoColumn, not (toGridExtensions in FOptions.MiscOptions)); ColumnLeft := R.Left; ColumnRight := R.Right; end else @@ -31890,7 +31965,7 @@ var Run: PVirtualNode; NextFunction: TGetNextNodeProc; begin - if not FSelectionLocked and (toMultiSelect in FOptions.FSelectionOptions) then + if not FSelectionLocked and (toMultiSelect in FOptions.SelectionOptions) then begin ClearTempCache; if VisibleOnly then @@ -32222,7 +32297,7 @@ var Window := Handle; DC := GetDC(Handle); - if (toShowBackground in FOptions.FPaintOptions) and Assigned(FBackground.Graphic) then + if (toShowBackground in FOptions.PaintOptions) and Assigned(FBackground.Graphic) then Self.Brush.Style := bsClear else begin @@ -32291,7 +32366,7 @@ begin // Calculate the height delta right now as we need it for toChildrenAbove anyway. HeightDelta := -Integer(Node.TotalHeight) + Integer(NodeHeight[Node]); - if (FUpdateCount = 0) and (toAnimatedToggle in FOptions.FAnimationOptions) and not + if (FUpdateCount = 0) and (toAnimatedToggle in FOptions.AnimationOptions) and not (tsCollapsing in FStates) then begin if tsHint in Self.FStates then @@ -32305,7 +32380,7 @@ begin // on the position of the node to be collapsed. R1 := GetDisplayRect(Node, NoColumn, False); Mode2 := tamNoScroll; - if toChildrenAbove in FOptions.FPaintOptions then + if toChildrenAbove in FOptions.PaintOptions then begin PosHoldable := (FOffsetY + (Integer(Node.TotalHeight) - Integer(NodeHeight[Node]))) <= 0; NodeInView := R1.Top < ClientHeight; @@ -32313,7 +32388,7 @@ begin StepsR1 := 0; if NodeInView then begin - if PosHoldable or not (toAdvancedAnimatedToggle in FOptions.FAnimationOptions) then + if PosHoldable or not (toAdvancedAnimatedToggle in FOptions.AnimationOptions) then begin // Scroll the child nodes down. Mode1 := tamScrollDown; @@ -32335,7 +32410,7 @@ begin begin if (Integer(FRangeY) + FOffsetY - R1.Bottom + HeightDelta >= ClientHeight - R1.Bottom) or (Integer(FRangeY) <= ClientHeight) or (FOffsetY = 0) or not - (toAdvancedAnimatedToggle in FOptions.FAnimationOptions) then + (toAdvancedAnimatedToggle in FOptions.AnimationOptions) then begin // Do a simple scroll up over the child nodes. Mode1 := tamScrollUp; @@ -32376,7 +32451,7 @@ begin DoCollapsed(Node); // Remove child nodes now, if enabled. - if (toAutoFreeOnCollapse in FOptions.FAutoOptions) and (Node.ChildCount > 0) then + if (toAutoFreeOnCollapse in FOptions.AutoOptions) and (Node.ChildCount > 0) then begin DeleteChildren(Node); Include(Node.States, vsHasChildren); @@ -32410,7 +32485,7 @@ begin until Child = nil; // Getting the display rectangle is already done here as it is needed for toChildrenAbove in any case. - if (toChildrenAbove in FOptions.FPaintOptions) or (FUpdateCount = 0) then + if (toChildrenAbove in FOptions.PaintOptions) or (FUpdateCount = 0) then begin with ToggleData do begin @@ -32418,7 +32493,7 @@ begin Mode2 := tamNoScroll; TotalFit := HeightDelta + Integer(NodeHeight[Node]) <= ClientHeight; - if toChildrenAbove in FOptions.FPaintOptions then + if toChildrenAbove in FOptions.PaintOptions then begin // The main goal with toChildrenAbove being set is to keep the nodes visual position so the user does // not get confused. Therefore we need to scroll the view when the expanding is done. @@ -32440,7 +32515,7 @@ begin begin // Do animated expanding if enabled. if (ToggleData.R1.Top < ClientHeight) and ([tsPainting, tsExpanding] * FStates = []) and - (toAnimatedToggle in FOptions.FAnimationOptions)then + (toAnimatedToggle in FOptions.AnimationOptions)then begin if tsHint in Self.FStates then Application.CancelHint; @@ -32448,12 +32523,12 @@ begin // animated expanding with ToggleData do begin - if toChildrenAbove in FOptions.FPaintOptions then + if toChildrenAbove in FOptions.PaintOptions then begin // At first check if we hold the position, which is the most common case. - if not (toAdvancedAnimatedToggle in FOptions.FAnimationOptions) or + if not (toAdvancedAnimatedToggle in FOptions.AnimationOptions) or (PosHoldable and ( (NodeInView and ChildrenInView) or not - (toAutoScrollOnExpand in FOptions.FAutoOptions) )) then + (toAutoScrollOnExpand in FOptions.AutoOptions) )) then begin Mode1 := tamScrollUp; R1 := Rect(R1.Left, 0, R1.Right, R1.Top); @@ -32465,7 +32540,7 @@ begin Mode1 := tamScrollDown; Mode2 := tamScrollUp; R2 := Rect(R1.Left, 0, R1.Right, R1.Top); - if not (toAutoScrollOnExpand in FOptions.FAutoOptions) then + if not (toAutoScrollOnExpand in FOptions.AutoOptions) then begin // If we shall not or cannot scroll to the desired extent we calculate the new position (with // max FOffsetY applied) and animate it that way. @@ -32516,8 +32591,8 @@ begin else begin // toChildrenAbove is not set. - if (PosHoldable and ChildrenInView) or not (toAutoScrollOnExpand in FOptions.FAutoOptions) or not - (toAdvancedAnimatedToggle in FOptions.FAnimationOptions) or (R1.Top <= 0) then + if (PosHoldable and ChildrenInView) or not (toAutoScrollOnExpand in FOptions.AutoOptions) or not + (toAdvancedAnimatedToggle in FOptions.AnimationOptions) or (R1.Top <= 0) then begin // If the node will stay at its visual position, do a simple down-scroll. Mode1 := tamScrollDown; @@ -32550,8 +32625,8 @@ begin end; end; end; - if toAutoSort in FOptions.FAutoOptions then - Sort(Node, FHeader.FSortColumn, FHeader.FSortDirection, False); + if toAutoSort in FOptions.AutoOptions then + Sort(Node, FHeader.SortColumn, FHeader.SortDirection, False); end;// if UpdateCount = 0 Include(Node.States, vsExpanded); @@ -32575,14 +32650,14 @@ begin UpdateScrollBars(True); if [tsPainting, tsExpanding] * FStates = [] then begin - if (vsExpanded in Node.States) and ((toAutoScrollOnExpand in FOptions.FAutoOptions) or - (toChildrenAbove in FOptions.FPaintOptions)) then + if (vsExpanded in Node.States) and ((toAutoScrollOnExpand in FOptions.AutoOptions) or + (toChildrenAbove in FOptions.PaintOptions)) then begin - if toChildrenAbove in FOptions.FPaintOptions then + if toChildrenAbove in FOptions.PaintOptions then begin NeedFullInvalidate := True; if (PosHoldable and ChildrenInView and NodeInView) or not - (toAutoScrollOnExpand in FOptions.FAutoOptions) then + (toAutoScrollOnExpand in FOptions.AutoOptions) then SetOffsetY(FOffsetY - Integer(HeightDelta)) else if TotalFit and NodeInView then @@ -32610,7 +32685,7 @@ begin begin // If we have collapsed the node or toAutoScrollOnExpand is not set, we try to keep the nodes // visual position. - if toChildrenAbove in FOptions.FPaintOptions then + if toChildrenAbove in FOptions.PaintOptions then SetOffsetY(FOffsetY - Integer(HeightDelta)); NeedFullInvalidate := True; end; @@ -32648,7 +32723,7 @@ procedure TBaseVirtualTree.UpdateHorizontalRange; begin if FHeader.UseColumns then - SetRangeX(FHeader.FColumns.TotalWidth) + SetRangeX(FHeader.Columns.TotalWidth) else SetRangeX(GetMaxRightExtend); end; @@ -32946,6 +33021,19 @@ end; //---------------------------------------------------------------------------------------------------------------------- +procedure TVTEdit.ClearLink; +begin + FLink := nil +end; + +//---------------------------------------------------------------------------------------------------------------------- +procedure TVTEdit.ClearRefLink; +begin + FRefLink := nil +end; + +//---------------------------------------------------------------------------------------------------------------------- + function TVTEdit.CalcMinHeight: Integer; var textHeight : Integer; @@ -32971,7 +33059,7 @@ end; procedure TVTEdit.CMExit(var Message: TMessage); begin - if Assigned(FLink) and not FLink.FStopping then + if Assigned(FLink) and not FLink.Stopping then with FLink, FTree do begin if (toAutoAcceptEditChange in TreeOptions.StringOptions) then @@ -32994,8 +33082,8 @@ end; procedure TVTEdit.CNCommand(var Message: TWMCommand); begin - if Assigned(FLink) and Assigned(FLink.FTree) and (Message.NotifyCode = EN_UPDATE) and - not (vsMultiline in FLink.FNode.States) then + if Assigned(FLink) and Assigned(FLink.Tree) and (Message.NotifyCode = EN_UPDATE) and + not (vsMultiline in FLink.Node.States) then // Instead directly calling AutoAdjustSize it is necessary on Win9x/Me to decouple this notification message // and eventual resizing. Hence we use a message to accomplish that. AutoAdjustSize() @@ -33019,7 +33107,7 @@ procedure TVTEdit.WMDestroy(var Message: TWMDestroy); begin // If editing stopped by other means than accept or cancel then we have to do default processing for // pending changes. - if Assigned(FLink) and not FLink.FStopping and not (csRecreating in Self.ControlState) then + if Assigned(FLink) and not FLink.Stopping and not (csRecreating in Self.ControlState) then begin with FLink, FTree do begin @@ -33058,7 +33146,7 @@ var EditOptions: TVTEditOptions; Column: TVirtualTreeColumn; begin - Tree := FLink.FTree; + Tree := FLink.Tree; case Message.CharCode of VK_ESCAPE: begin @@ -33066,7 +33154,7 @@ begin end; VK_RETURN: begin - EndEdit := not (vsMultiline in FLink.FNode.States); + EndEdit := not (vsMultiline in FLink.Node.States); if not EndEdit then begin // If a multiline node is being edited the finish editing only if Ctrl+Enter was pressed, @@ -33076,10 +33164,10 @@ begin end; if EndEdit then begin - Tree := FLink.FTree; - FLink.FTree.InvalidateNode(FLink.FNode); - NextNode := Tree.GetNextVisible(FLink.FNode, True); - FLink.FTree.DoEndEdit; + Tree := FLink.Tree; + FLink.Tree.InvalidateNode(FLink.Node); + NextNode := Tree.GetNextVisible(FLink.Node, True); + FLink.Tree.DoEndEdit; // get edit options for column as priority. If column has toDefaultEdit // use global edit options for tree @@ -33142,13 +33230,13 @@ begin end; VK_UP: begin - if not (vsMultiline in FLink.FNode.States) then + if not (vsMultiline in FLink.Node.States) then Message.CharCode := VK_LEFT; inherited; end; VK_DOWN: begin - if not (vsMultiline in FLink.FNode.States) then + if not (vsMultiline in FLink.Node.States) then Message.CharCode := VK_RIGHT; inherited; end; @@ -33156,11 +33244,11 @@ begin begin if Tree.IsEditing then begin - Tree.InvalidateNode(FLink.FNode); + Tree.InvalidateNode(FLink.Node); if ssShift in KeyDataToShiftState(Message.KeyData) then - NextNode := Tree.GetPreviousVisible(FLink.FNode, True) // Shift+Tab goes to previous mode + NextNode := Tree.GetPreviousVisible(FLink.Node, True) // Shift+Tab goes to previous mode else - NextNode := Tree.GetNextVisible(FLink.FNode, True); + NextNode := Tree.GetNextVisible(FLink.Node, True); Tree.EndEditNode; // check NextNode, otherwise we got AV if NextNode <> nil then @@ -33196,18 +33284,18 @@ procedure TVTEdit.AutoAdjustSize; var Size: TSize; begin - if not (vsMultiline in FLink.FNode.States) and not (toGridExtensions in FLink.FTree.FOptions.FMiscOptions{see issue #252}) then + if not (vsMultiline in FLink.Node.States) and not (toGridExtensions in FLink.Tree.TreeOptions.MiscOptions{see issue #252}) then begin // avoid flicker SendMessage(Handle, WM_SETREDRAW, 0, 0); try Size := GetTextSize; - Inc(Size.cx, 2 * FLink.FTree.FTextMargin); + Inc(Size.cx, 2 * FLink.Tree.FTextMargin); // Repaint associated node if the edit becomes smaller. if Size.cx < Width then - FLink.FTree.Invalidate(); + FLink.Tree.Invalidate(); - if FLink.FAlignment = taRightJustify then + if FLink.Alignment = taRightJustify then FLink.SetBounds(Rect(Left + Width - Size.cx, Top, Left + Width, Top + Max(Size.cy, Height))) else FLink.SetBounds(Rect(Left, Top, Left + Size.cx, Top + Max(Size.cy, Height))); @@ -33223,7 +33311,7 @@ procedure TVTEdit.CreateParams(var Params: TCreateParams); begin inherited; - if not Assigned(FLink.FNode) then + if not Assigned(FLink.Node) then exit; // Prevent AV exceptions occasionally seen in code below // Only with multiline style we can use the text formatting rectangle. @@ -33231,9 +33319,9 @@ begin with Params do begin Style := Style or ES_MULTILINE; - if vsMultiline in FLink.FNode.States then + if vsMultiline in FLink.Node.States then Style := Style and not (ES_AUTOHSCROLL or WS_HSCROLL) or WS_VSCROLL or ES_AUTOVSCROLL; - if tsUseThemes in FLink.FTree.FStates then + if tsUseThemes in FLink.Tree.FStates then begin Style := Style and not WS_BORDER; ExStyle := ExStyle or WS_EX_CLIENTEDGE; @@ -33266,7 +33354,7 @@ end; procedure TVTEdit.KeyPress(var Key: Char); begin - if (Key = #13) and Assigned(FLink) and not (vsMultiline in FLink.FNode.States) then + if (Key = #13) and Assigned(FLink) and not (vsMultiline in FLink.Node.States) then Key := #0; // Filter out return keys as they will be added to the text, avoids #895 inherited; end; @@ -33344,8 +33432,8 @@ begin FStopping := True; FEdit.Hide; FTree.CancelEditNode; - FEdit.FLink := nil; - FEdit.FRefLink := nil; + FEdit.ClearLink; + FEdit.ClearRefLink; end; end; @@ -33361,8 +33449,8 @@ begin if FEdit.Modified then FTree.Text[FNode, FColumn] := FEdit.Text; FEdit.Hide; - FEdit.FLink := nil; - FEdit.FRefLink := nil; + FEdit.ClearLink; + FEdit.ClearRefLink; except FStopping := False; raise; @@ -33499,9 +33587,9 @@ begin end; lOffset := IfThen(vsMultiline in FNode.States, 0, 2); - if tsUseThemes in FTree.FStates then + if tsUseThemes in FTree.TreeStates then Inc(lOffset); - InflateRect(R, -FTree.FTextMargin + lOffset, lOffset); + InflateRect(R, -FTree.TextMargin + lOffset, lOffset); if not (vsMultiline in FNode.States) then begin tOffset := FTextBounds.Top - FEdit.Top; @@ -33679,7 +33767,7 @@ begin else Canvas.Font.Color := FColors.DisabledColor; - if (toHotTrack in FOptions.FPaintOptions) and (Node = FCurrentHotNode) then + if (toHotTrack in FOptions.PaintOptions) and (Node = FCurrentHotNode) then begin if not (tsUseExplorerTheme in FStates) then begin @@ -33691,12 +33779,12 @@ begin // Change the font color only if the node also is drawn in selected style. if poDrawSelection in PaintOptions then begin - if (Column = FFocusedColumn) or (toFullRowSelect in FOptions.FSelectionOptions) then + if (Column = FFocusedColumn) or (toFullRowSelect in FOptions.SelectionOptions) then begin if Node = FDropTargetNode then begin if ((FLastDropMode = dmOnNode) or (vsSelected in Node.States)) then - Canvas.Font.Color := FColors.GetSelectedNodeFontColor(Focused or (toPopupMode in FOptions.FPaintOptions)); + Canvas.Font.Color := FColors.GetSelectedNodeFontColor(Focused or (toPopupMode in FOptions.PaintOptions)); end else if vsSelected in Node.States then @@ -33808,7 +33896,7 @@ begin with PaintInfo do begin Canvas.Font := Font; - if toFullRowSelect in FOptions.FSelectionOptions then + if toFullRowSelect in FOptions.SelectionOptions then begin if Node = FDropTargetNode then begin @@ -33820,7 +33908,7 @@ begin else if vsSelected in Node.States then begin - if Focused or (toPopupMode in FOptions.FPaintOptions) then + if Focused or (toPopupMode in FOptions.PaintOptions) then Canvas.Font.Color := FColors.GetSelectedNodeFontColor(Focused) else Canvas.Font.Color := FColors.NodeFontColor; @@ -33992,8 +34080,8 @@ procedure TCustomVirtualStringTree.AdjustPaintCellRect(var PaintInfo: TVTPaintIn // Note: the autospan feature can only be used with left-to-right layout. begin - if (toAutoSpanColumns in FOptions.FAutoOptions) and FHeader.UseColumns and (PaintInfo.BidiMode = bdLeftToRight) then - with FHeader.FColumns, PaintInfo do + if (toAutoSpanColumns in FOptions.AutoOptions) and FHeader.UseColumns and (PaintInfo.BidiMode = bdLeftToRight) then + with FHeader.Columns, PaintInfo do begin // Start with the directly following column. NextNonEmpty := GetNextVisibleColumn(Column); @@ -34124,7 +34212,7 @@ function TCustomVirtualStringTree.DoGetNodeExtraWidth(Node: PVirtualNode; Column Canvas: TCanvas = nil): Integer; begin - if not (toShowStaticText in TreeOptions.FStringOptions) then + if not (toShowStaticText in TreeOptions.StringOptions) then Exit(0); if Canvas = nil then Canvas := Self.Canvas; @@ -34250,7 +34338,7 @@ begin PaintNormalText(PaintInfo, TextOutFlags, lEventArgs.CellText); // ... and afterwards the static text if not centered and the node is not multiline enabled. - if (Alignment <> taCenter) and not (vsMultiline in PaintInfo.Node.States) and (toShowStaticText in TreeOptions.FStringOptions) and not lEventArgs.StaticText.IsEmpty then + if (Alignment <> taCenter) and not (vsMultiline in PaintInfo.Node.States) and (toShowStaticText in TreeOptions.StringOptions) and not lEventArgs.StaticText.IsEmpty then PaintStaticText(PaintInfo, lEventArgs.StaticTextAlignment, lEventArgs.StaticText); finally RestoreFontChangeEvent(PaintInfo.Canvas); @@ -34291,13 +34379,17 @@ procedure TCustomVirtualStringTree.DoTextDrawing(var PaintInfo: TVTPaintInfo; co var DefaultDraw: Boolean; - + lText: string; begin DefaultDraw := True; if Assigned(FOnDrawText) then FOnDrawText(Self, PaintInfo.Canvas, PaintInfo.Node, PaintInfo.Column, Text, CellRect, DefaultDraw); + if ((DrawFormat and DT_RIGHT) > 0) and (TFontStyle.fsItalic in PaintInfo.Canvas.Font.Style) then + lText := Text + ' ' + else + lText := Text; if DefaultDraw then - Winapi.Windows.DrawTextW(PaintInfo.Canvas.Handle, PWideChar(Text), Length(Text), CellRect, DrawFormat); + Winapi.Windows.DrawTextW(PaintInfo.Canvas.Handle, PWideChar(lText), Length(lText), CellRect, DrawFormat); end; //---------------------------------------------------------------------------------------------------------------------- @@ -34432,9 +34524,9 @@ begin OldOption := TOldVTStringOption(GetEnumValue(TypeInfo(TOldVTStringOption), EnumName)); case OldOption of soSaveCaptions: - StringOptions := FStringOptions + [toSaveCaptions]; + StringOptions := StringOptions + [toSaveCaptions]; soShowStaticText: - StringOptions := FStringOptions + [toShowStaticText]; + StringOptions := StringOptions + [toShowStaticText]; end; end; end; @@ -34485,7 +34577,7 @@ var begin inherited; - if (toSaveCaptions in TreeOptions.FStringOptions) and (Node <> FRoot) and + if (toSaveCaptions in TreeOptions.StringOptions) and (Node <> FRoot) and (vsInitialized in Node.States) then with Stream do begin diff --git a/components/virtualtreeview/Virtual-TreeView.dspec b/components/virtualtreeview/Virtual-TreeView.dspec new file mode 100644 index 00000000..a8826551 --- /dev/null +++ b/components/virtualtreeview/Virtual-TreeView.dspec @@ -0,0 +1,162 @@ +{ + "metadata": { + "id": "JAM.VirtualTreeView", + "version": "7.4.0", + "description": "Virtual TreeView VCL Component", + "authors": "Joachim Marder", + "projectUrl": "https://github.com/Virtual-TreeView/Virtual-TreeView", + "license": "MPL-1.1, LGPL-2.0+", + "copyright": "Various, See project page", + "tags": "VCL, TreeView" + }, + "targetPlatforms": [ + { + "compiler": "XE3", + "platforms": "Win32, Win64", + "template": "default", + "variables" : { + "libsuffix" : "17" + } + }, + { + "compiler": "XE4", + "platforms": "Win32, Win64", + "template": "default", + "variables" : { + "libsuffix" : "18" + } + }, + { + "compiler": "XE5", + "platforms": "Win32, Win64", + "template": "default", + "variables" : { + "libsuffix" : "19" + } + }, + { + "compiler": "XE6", + "platforms": "Win32, Win64", + "template": "default", + "variables" : { + "libsuffix" : "20" + } + }, + { + "compiler": "XE7", + "platforms": "Win32, Win64", + "template": "default", + "variables" : { + "libsuffix" : "21" + } + }, + { + "compiler": "XE8", + "platforms": "Win32, Win64", + "template": "default", + "variables" : { + "libsuffix" : "22" + } + }, + { + "compiler": "10.0", + "platforms": "Win32, Win64", + "template": "default", + "variables" : { + "libsuffix" : "23", + "compiler" : "$compilerNoPoint$" + } + }, + { + "compiler": "10.1", + "platforms": "Win32, Win64", + "template": "default", + "variables" : { + "libsuffix" : "24" + } + }, + { + "compiler": "10.2", + "platforms": "Win32, Win64", + "template": "default", + "variables" : { + "libsuffix" : "25" + } + }, + { + "compiler": "10.3", + "platforms": "Win32, Win64", + "template": "default", + "variables" : { + "libsuffix" : "26" + } + }, + { + "compiler": "10.4", + "platforms": "Win32, Win64", + "template": "default", + "variables" : { + "libsuffix" : "27" + } + } + ], + "templates": [ + { + "comment": "all other compiler versions follow normal folder naming", + "name": "default", + "source": [ + { + "src": ".\\Source\\*.pas", + "dest": "Source" + }, + { + "src": ".\\Source\\*.res", + "dest": "Source" + }, + { + "src": ".\\Design\\*.*", + "dest": "Design" + }, + { + "src": ".\\packages\\Rad Studio $compiler$\\**", + "flatten": false, + "dest": "packages\\Rad Studio $compiler$" + } + ], + "searchPaths": [ + { + "path": "Source", + "source": true + } + ], + "build": [ + { + "id": "VirtualTreesR", + "project": ".\\Packages\\Rad Studio $compiler$\\VirtualTreesR.dproj", + "buildForDesign": true, + "buildForDesignComment" : "when true, will also build win32 if the platform is not win32, so that other packages that need this for design will work" + }, + { + "id": "VirtualTreesD", + "project": ".\\Packages\\Rad Studio $compiler$\\VirtualTreesD.dproj", + "designOnly" : true, + "designOnlyComment" : "designOnly forces compilation with win32 compiler" + } + ], + "runtime": [ + { + "buildId": "VirtualTreesR", + "src": "bin\\VirtualTreesR$libsuffix$.bpl", + "copyLocal": true + } + ], + "design": [ + { + "buildId": "VirtualTreesD", + "src": "bin\\VirtualTreesD$libsuffix$.bpl", + "install": true + } + ] + } + ] +}