Merge updated VirtualTreeView component source to r229

This commit is contained in:
Ansgar Becker
2009-10-19 09:48:48 +00:00
parent b1a65036fd
commit 08d32fea64

View File

@ -24,7 +24,19 @@ unit VirtualTrees;
// (C) 1999-2001 digital publishing AG. All Rights Reserved. // (C) 1999-2001 digital publishing AG. All Rights Reserved.
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
// //
// October 2009
// - Bug fix: enabling checkbox support for a column is now possible without assigning a dummy imagelist
// - Bug fix: checkboxes in the header are now correctly aligned
// - Improvement: changed TBaseVirtualTree.PaintCheckImage to be usable by TVirtualTreeColumns.PaintHeader to be
// able to paint themed header checkboxes
// - Bug fix: TBaseVirtualTree.GetCheckImage now correctly handles cases when Node is nil and ImgCheckType is either
// ctTriStateCheckBox or ctNone
// - Bug fix: TBaseVirtualTree.HasImage now implicitly initializes the given node if needed to avoid requesting the
// imageindex for nodes that are not initialized
// - Bug fix: fixed possible AV when setting toExplorerTheme with no columns defined
// - Improvement: new events TBaseVirtualTree.OnSaveTree and TBaseVirtualTree.OnLoadTree
// September 2009 // September 2009
// - Bug fix: TBaseVirtualTree.OnColumnClick will no longer be triggered twice
// - Improvement: new TVirtualNodeInitState ivsReInit to indicate that a node is about to be re-initialized // - Improvement: new TVirtualNodeInitState ivsReInit to indicate that a node is about to be re-initialized
// - Bug fix: TCustomVirtualStringTree.DoTextMeasuring now makes use of the parameter Width of the // - Bug fix: TCustomVirtualStringTree.DoTextMeasuring now makes use of the parameter Width of the
// OnMeasureTextWidth event // OnMeasureTextWidth event
@ -1737,6 +1749,7 @@ type
tsValidationNeeded, // Something in the structure of the tree has changed. The cache needs validation. tsValidationNeeded, // Something in the structure of the tree has changed. The cache needs validation.
tsVCLDragging, // VCL drag'n drop in progress. tsVCLDragging, // VCL drag'n drop in progress.
tsVCLDragPending, // One-shot flag to avoid clearing the current selection on implicit mouse up for VCL drag. tsVCLDragPending, // One-shot flag to avoid clearing the current selection on implicit mouse up for VCL drag.
tsVCLDragFinished, // Flag to avoid triggering the OnColumnClick event twice
tsWheelPanning, // Wheel mouse panning is active or soon will be. tsWheelPanning, // Wheel mouse panning is active or soon will be.
tsWheelScrolling, // Wheel mouse scrolling is active or soon will be. tsWheelScrolling, // Wheel mouse scrolling is active or soon will be.
tsWindowCreating, // Set during window handle creation to avoid frequent unnecessary updates. tsWindowCreating, // Set during window handle creation to avoid frequent unnecessary updates.
@ -2025,6 +2038,7 @@ type
var HelpContext: Integer) of object; var HelpContext: Integer) of object;
TVTCreateEditorEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TVTCreateEditorEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
out EditLink: IVTEditLink) of object; out EditLink: IVTEditLink) of object;
TVTSaveTreeEvent = procedure(Sender: TBaseVirtualTree; Stream: TStream) of object;
TVTSaveNodeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream) of object; TVTSaveNodeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream) of object;
// header/column events // header/column events
@ -2348,6 +2362,10 @@ type
// (see OnLoadNode) to give the application the opportunity to save // (see OnLoadNode) to give the application the opportunity to save
// their node specific, persistent data (note: never save memory // their node specific, persistent data (note: never save memory
// references) // references)
FOnLoadTree, // called after the tree has been loaded from a stream to allow an
// application to load their own data saved in OnSaveTree
FOnSaveTree: TVTSaveTreeEvent; // called after the tree has been saved to a stream to allow an
// application to save its own data
// header/column mouse events // header/column mouse events
FOnAfterAutoFitColumn: TVTAfterAutoFitColumnEvent; FOnAfterAutoFitColumn: TVTAfterAutoFitColumnEvent;
@ -2786,7 +2804,7 @@ type
procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure OriginalWMNCPaint(DC: HDC); virtual; procedure OriginalWMNCPaint(DC: HDC); virtual;
procedure Paint; override; procedure Paint; override;
procedure PaintCheckImage(const PaintInfo: TVTPaintInfo); virtual; procedure PaintCheckImage(Canvas: TCanvas; const ImageInfo: TVTImageInfo; Selected: Boolean); virtual;
procedure PaintImage(var PaintInfo: TVTPaintInfo; ImageInfoIndex: TVTImageInfoIndex; DoOverlay: Boolean); virtual; procedure PaintImage(var PaintInfo: TVTPaintInfo; ImageInfoIndex: TVTImageInfoIndex; DoOverlay: Boolean); virtual;
procedure PaintNodeButton(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const R: TRect; ButtonX, procedure PaintNodeButton(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const R: TRect; ButtonX,
ButtonY: Integer; BidiMode: TBiDiMode); virtual; ButtonY: Integer; BidiMode: TBiDiMode); virtual;
@ -2976,6 +2994,7 @@ type
property OnInitNode: TVTInitNodeEvent read FOnInitNode write FOnInitNode; property OnInitNode: TVTInitNodeEvent read FOnInitNode write FOnInitNode;
property OnKeyAction: TVTKeyActionEvent read FOnKeyAction write FOnKeyAction; property OnKeyAction: TVTKeyActionEvent read FOnKeyAction write FOnKeyAction;
property OnLoadNode: TVTSaveNodeEvent read FOnLoadNode write FOnLoadNode; property OnLoadNode: TVTSaveNodeEvent read FOnLoadNode write FOnLoadNode;
property OnLoadTree: TVTSaveTreeEvent read FOnLoadTree write FOnLoadTree;
property OnMeasureItem: TVTMeasureItemEvent read FOnMeasureItem write FOnMeasureItem; property OnMeasureItem: TVTMeasureItemEvent read FOnMeasureItem write FOnMeasureItem;
property OnNodeCopied: TVTNodeCopiedEvent read FOnNodeCopied write FOnNodeCopied; property OnNodeCopied: TVTNodeCopiedEvent read FOnNodeCopied write FOnNodeCopied;
property OnNodeCopying: TVTNodeCopyingEvent read FOnNodeCopying write FOnNodeCopying; property OnNodeCopying: TVTNodeCopyingEvent read FOnNodeCopying write FOnNodeCopying;
@ -2989,6 +3008,7 @@ type
property OnRenderOLEData: TVTRenderOLEDataEvent read FOnRenderOLEData write FOnRenderOLEData; property OnRenderOLEData: TVTRenderOLEDataEvent read FOnRenderOLEData write FOnRenderOLEData;
property OnResetNode: TVTChangeEvent read FOnResetNode write FOnResetNode; property OnResetNode: TVTChangeEvent read FOnResetNode write FOnResetNode;
property OnSaveNode: TVTSaveNodeEvent read FOnSaveNode write FOnSaveNode; property OnSaveNode: TVTSaveNodeEvent read FOnSaveNode write FOnSaveNode;
property OnSaveTree: TVTSaveTreeEvent read FOnSaveTree write FOnSaveTree;
property OnScroll: TVTScrollEvent read FOnScroll write FOnScroll; property OnScroll: TVTScrollEvent read FOnScroll write FOnScroll;
property OnShowScrollbar: TVTScrollbarShowEvent read FOnShowScrollbar write FOnShowScrollbar; property OnShowScrollbar: TVTScrollbarShowEvent read FOnShowScrollbar write FOnShowScrollbar;
property OnStateChange: TVTStateChangeEvent read FOnStateChange write FOnStateChange; property OnStateChange: TVTStateChangeEvent read FOnStateChange write FOnStateChange;
@ -3618,6 +3638,7 @@ type
property OnKeyPress; property OnKeyPress;
property OnKeyUp; property OnKeyUp;
property OnLoadNode; property OnLoadNode;
property OnLoadTree;
property OnMeasureItem; property OnMeasureItem;
property OnMeasureTextWidth; property OnMeasureTextWidth;
property OnMouseDown; property OnMouseDown;
@ -3637,6 +3658,7 @@ type
property OnResetNode; property OnResetNode;
property OnResize; property OnResize;
property OnSaveNode; property OnSaveNode;
property OnSaveTree;
property OnScroll; property OnScroll;
property OnShortenString; property OnShortenString;
property OnShowScrollbar; property OnShowScrollbar;
@ -3865,6 +3887,7 @@ type
property OnKeyPress; property OnKeyPress;
property OnKeyUp; property OnKeyUp;
property OnLoadNode; property OnLoadNode;
property OnLoadTree;
property OnMeasureItem; property OnMeasureItem;
property OnMouseDown; property OnMouseDown;
property OnMouseMove; property OnMouseMove;
@ -3882,6 +3905,7 @@ type
property OnResetNode; property OnResetNode;
property OnResize; property OnResize;
property OnSaveNode; property OnSaveNode;
property OnSaveTree;
property OnScroll; property OnScroll;
property OnShowScrollbar; property OnShowScrollbar;
property OnStartDock; property OnStartDock;
@ -8798,7 +8822,8 @@ begin
if not FCheckBox then if not FCheckBox then
HeaderGlyphSize := Point(FImages.Width, FImages.Height) HeaderGlyphSize := Point(FImages.Width, FImages.Height)
else else
HeaderGlyphSize := Point(Treeview.CheckImages.Width, Treeview.CheckImages.Height) with TBaseVirtualTree.GetCheckImageListFor(FHeader.Treeview.CheckImageKind) do
HeaderGlyphSize := Point(Width, Height)
else else
HeaderGlyphSize := Point(0, 0); HeaderGlyphSize := Point(0, 0);
if UseSortGlyph then if UseSortGlyph then
@ -9065,6 +9090,8 @@ begin
HeaderGlyphPos.X := MinLeft; HeaderGlyphPos.X := MinLeft;
if Layout = blGlyphLeft then if Layout = blGlyphLeft then
MinLeft := HeaderGlyphPos.X + HeaderGlyphSize.X + FSpacing; MinLeft := HeaderGlyphPos.X + HeaderGlyphSize.X + FSpacing;
if FCheckBox and (Owner.Header.MainColumn = Self.Index) then
Dec(HeaderGlyphPos.X, 2 + 2 * Integer(toShowRoot in Owner.FHeader.Treeview.TreeOptions.FPaintOptions));
// Finally transform header glyph to its actual position. // Finally transform header glyph to its actual position.
with HeaderGlyphPos do with HeaderGlyphPos do
begin begin
@ -10731,10 +10758,10 @@ var
SavedDC: Integer; SavedDC: Integer;
Temp: TRect; Temp: TRect;
ColCaptionText: UnicodeString; ColCaptionText: UnicodeString;
ColImages: TCustomImageList; ColImageInfo: TVTImageInfo;
ColImageIndex: Integer;
begin begin
ColImageInfo.Ghosted := False;
Run := FHeader.Treeview.FHeaderRect; Run := FHeader.Treeview.FHeaderRect;
FHeaderBitmap.Width := Max(Run.Right, R.Right - R.Left); FHeaderBitmap.Width := Max(Run.Right, R.Right - R.Left);
FHeaderBitmap.Height := Run.Bottom; FHeaderBitmap.Height := Run.Bottom;
@ -10878,7 +10905,8 @@ begin
else else
DropMark := dmmNone; DropMark := dmmNone;
IsEnabled := (coEnabled in FOptions) and (FHeader.Treeview.Enabled); IsEnabled := (coEnabled in FOptions) and (FHeader.Treeview.Enabled);
ShowHeaderGlyph := (hoShowImages in FHeader.FOptions) and Assigned(Images) and (FImageIndex > -1); ShowHeaderGlyph := (hoShowImages in FHeader.FOptions) and
((Assigned(Images) and (FImageIndex > -1)) or FCheckBox);
ShowSortGlyph := (Integer(FPositionToIndex[I]) = FHeader.FSortColumn) and (hoShowSortGlyphs in FHeader.FOptions); ShowSortGlyph := (Integer(FPositionToIndex[I]) = FHeader.FSortColumn) and (hoShowSortGlyphs in FHeader.FOptions);
WrapCaption := coWrapCaption in FOptions; WrapCaption := coWrapCaption in FOptions;
@ -10971,27 +10999,28 @@ begin
begin begin
if not FCheckBox then if not FCheckBox then
begin begin
ColImages := Images; ColImageInfo.Images := Images;
ColImageIndex := FImageIndex; Images.Draw(FHeaderBitmap.Canvas, GlyphPos.X, GlyphPos.Y, FImageIndex, IsEnabled);
end end
else else
begin begin
with Header.Treeview do with Header.Treeview do
begin begin
ColImages := GetCheckImageListFor(CheckImageKind); ColImageInfo.Images := GetCheckImageListFor(CheckImageKind);
ColImageIndex := GetCheckImage(nil, FCheckType, FCheckState, IsEnabled); ColImageInfo.Index := GetCheckImage(nil, FCheckType, FCheckState, IsEnabled);
ColImageInfo.XPos := GlyphPos.X;
ColImageInfo.YPos := GlyphPos.Y;
PaintCheckImage(FHeaderBitmap.Canvas, ColImageInfo, False);
end; end;
end; end;
ColImages.Draw( FHeaderBitmap.Canvas, GlyphPos.X, GlyphPos.Y, ColImageIndex, IsEnabled );
FHasImage := True; FHasImage := True;
with FImageRect do with FImageRect do
begin begin
Left := GlyphPos.X; Left := GlyphPos.X;
Top := GlyphPos.Y; Top := GlyphPos.Y;
Right := Left + ColImages.Width; Right := Left + ColImageInfo.Images.Width;
Bottom := Top + ColImages.Height; Bottom := Top + ColImageInfo.Images.Height;
end; end;
end; end;
@ -15498,7 +15527,7 @@ var
if IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions) then if IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions) then
begin begin
if not (coParentColor in FHeader.FColumns[FHeader.FMainColumn].FOptions) then if (FHeader.FMainColumn >= 0) and not (coParentColor in FHeader.FColumns[FHeader.FMainColumn].FOptions) then
Brush.Color := FHeader.FColumns[FHeader.FMainColumn].Color Brush.Color := FHeader.FColumns[FHeader.FMainColumn].Color
else else
Brush.Color := Self.Color; Brush.Color := Self.Color;
@ -17052,7 +17081,7 @@ begin
if DragMessage = dmDragEnter then if DragMessage = dmDragEnter then
DoStateChange([tsVCLDragging]); DoStateChange([tsVCLDragging]);
if DragMessage = dmDragLeave then if DragMessage = dmDragLeave then
DoStateChange([], [tsVCLDragging]); DoStateChange([tsVCLDragFinished], [tsVCLDragging]);
if DragMessage = dmDragMove then if DragMessage = dmDragMove then
with ScreenToClient(Pos) do with ScreenToClient(Pos) do
@ -22110,7 +22139,10 @@ var
P: TPoint; P: TPoint;
begin begin
DoStateChange([], [tsVCLDragPending, tsVCLDragging, tsUserDragObject]); if [tsVCLDragPending, tsVCLDragging, tsVCLDragFinished] * FStates = [] then
Exit;
DoStateChange([], [tsVCLDragPending, tsVCLDragging, tsUserDragObject, tsVCLDragFinished]);
GetCursorPos(P); GetCursorPos(P);
P := ScreenToClient(P); P := ScreenToClient(P);
@ -22577,22 +22609,26 @@ const
); );
var var
AType: TCheckType; IsHot: Boolean;
begin begin
if not Assigned(Node) then if Assigned(Node) then
Result := CheckStateToCheckImage[ImgCheckType, ImgCheckState, ImgEnabled, False] begin
ImgCheckType := Node.CheckType;
ImgCheckState := Node.CheckState;
ImgEnabled := not (vsDisabled in Node.States) and Enabled;
IsHot := Node = FCurrentHotNode;
end
else else
if Node.CheckType = ctNone then IsHot := False;
if ImgCheckType = ctTriStateCheckBox then
ImgCheckType := ctCheckBox;
if ImgCheckType = ctNone then
Result := -1 Result := -1
else else
begin Result := CheckStateToCheckImage[ImgCheckType, ImgCheckState, ImgEnabled, IsHot];
AType := Node.CheckType;
if AType = ctTriStateCheckBox then
AType := ctCheckBox;
Result := CheckStateToCheckImage[AType, Node.CheckState, not (vsDisabled in Node.States) and Enabled,
Node = FCurrentHotNode];
end;
end; end;
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
@ -22614,7 +22650,9 @@ begin
ckXP: ckXP:
Result := XPImages; Result := XPImages;
ckSystemDefault: ckSystemDefault:
Result := SystemCheckImages; ckSystemFlat: Result := SystemFlatCheckImages; Result := SystemCheckImages;
ckSystemFlat:
Result := SystemFlatCheckImages;
else else
Result := nil; Result := nil;
end; end;
@ -23549,12 +23587,16 @@ function TBaseVirtualTree.HasImage(Node: PVirtualNode; Kind: TVTImageKind; Colum
// Determines whether the given node has got an image of the given kind in the given column. // Determines whether the given node has got an image of the given kind in the given column.
// Returns True if so, otherwise False. // Returns True if so, otherwise False.
// The given node will be implicitly initialized if needed.
var var
Ghosted: Boolean; Ghosted: Boolean;
Index: Integer; Index: Integer;
begin begin
if not (vsInitialized in Node.States) then
InitNode(Node);
Index := -1; Index := -1;
Ghosted := False; Ghosted := False;
DoGetImageIndex(Node, Kind, Column, Ghosted, Index); DoGetImageIndex(Node, Kind, Column, Ghosted, Index);
@ -24555,7 +24597,7 @@ end;
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
procedure TBaseVirtualTree.PaintCheckImage(const PaintInfo: TVTPaintInfo); procedure TBaseVirtualTree.PaintCheckImage(Canvas: TCanvas; const ImageInfo: TVTImageInfo; Selected: Boolean);
var var
ForegroundColor: COLORREF; ForegroundColor: COLORREF;
@ -24563,7 +24605,7 @@ var
Details: TThemedElementDetails; Details: TThemedElementDetails;
begin begin
with PaintInfo, ImageInfo[iiCheck] do with ImageInfo do
begin begin
if (tsUseThemes in FStates) and (FCheckImageKind = ckSystemDefault) then if (tsUseThemes in FStates) and (FCheckImageKind = ckSystemDefault) then
begin begin
@ -24596,7 +24638,7 @@ begin
else else
with FCheckImages do with FCheckImages do
begin begin
if (vsSelected in Node.States) and not Ghosted then if Selected and not Ghosted then
begin begin
if Focused or (toPopupMode in FOptions.FPaintOptions) then if Focused or (toPopupMode in FOptions.FPaintOptions) then
ForegroundColor := ColorToRGB(FColors.FocusedSelectionColor) ForegroundColor := ColorToRGB(FColors.FocusedSelectionColor)
@ -25081,7 +25123,7 @@ begin
else else
FocusRect := InnerRect; FocusRect := InnerRect;
if Theme <> 0 then if tsUseExplorerTheme in FStates then
InflateRect(FocusRect, -1, -1); InflateRect(FocusRect, -1, -1);
Windows.DrawFocusRect(Handle, FocusRect); Windows.DrawFocusRect(Handle, FocusRect);
@ -30301,6 +30343,8 @@ begin
InternalAddFromStream(Stream, Version, Node); InternalAddFromStream(Stream, Version, Node);
end; end;
DoNodeCopied(nil); DoNodeCopied(nil);
if Assigned(FOnLoadTree) then
FOnLoadTree(Self, Stream);
finally finally
EndUpdate; EndUpdate;
end; end;
@ -30862,7 +30906,7 @@ begin
PaintNodeButton(Canvas, Node, Column, CellRect, ButtonX, ButtonY, BidiMode); PaintNodeButton(Canvas, Node, Column, CellRect, ButtonX, ButtonY, BidiMode);
if ImageInfo[iiCheck].Index > -1 then if ImageInfo[iiCheck].Index > -1 then
PaintCheckImage(PaintInfo); PaintCheckImage(Canvas, PaintInfo.ImageInfo[iiCheck], vsSelected in PaintInfo.Node.States);
end; end;
if ImageInfo[iiState].Index > -1 then if ImageInfo[iiState].Index > -1 then
@ -31690,6 +31734,8 @@ begin
Stream.WriteBuffer(Count, SizeOf(Count)); Stream.WriteBuffer(Count, SizeOf(Count));
WriteNode(Stream, Node); WriteNode(Stream, Node);
end; end;
if Assigned(FOnSaveTree) then
FOnSaveTree(Self, Stream);
end; end;
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------