LCL: TreeView - support showing and hiding TreeNodes properly. Issue #17366, patch from Krzysztof Dibowski

git-svn-id: trunk@32064 -
This commit is contained in:
juha 2011-08-26 17:46:56 +00:00
parent e500bcb51d
commit 8e308ffe4d
2 changed files with 49 additions and 13 deletions

View File

@ -2386,6 +2386,7 @@ type
FSubTreeCount: integer;// total of all child nodes and self
FText: string;
FTop: integer; // top coordinate
FVisible: Boolean;
function AreParentsExpanded: Boolean;
procedure BindToMultiSelected;
function CompareCount(CompareMe: Integer): Boolean;
@ -2432,6 +2433,7 @@ type
procedure SetSelectedIndex(AValue: Integer);
procedure SetStateIndex(AValue: Integer);
procedure SetText(const S: string);
procedure SetVisible(const AValue: Boolean);
procedure Unbind;
procedure UnbindFromMultiSelected;
procedure WriteData(Stream: TStream);
@ -2464,6 +2466,7 @@ type
function BottomExpanded: integer;
function GetParentNodeOfAbsoluteLevel(TheAbsoluteLevel: integer): TTreeNode;
function GetFirstChild: TTreeNode;
function GetFirstVisibleChild: TTreeNode;
function GetHandle: THandle;
function GetLastSibling: TTreeNode;
function GetLastChild: TTreeNode;
@ -2475,6 +2478,7 @@ type
function GetNextMultiSelected: TTreeNode;
function GetNextSibling: TTreeNode;
function GetNextVisible: TTreeNode;
function GetNextVisibleSibling: TTreeNode;
function GetPrev: TTreeNode;
function GetPrevChild(AValue: TTreeNode): TTreeNode;
function GetPrevExpanded: TTreeNode;
@ -2521,6 +2525,7 @@ type
property TreeNodes: TTreeNodes read GetTreeNodes;
property TreeView: TCustomTreeView read GetTreeView;
property Top: integer read GetTop;
property Visible: Boolean read FVisible write SetVisible default True;
end;
{ TTreeNodesEnumerator }

View File

@ -272,6 +272,7 @@ begin
FOwner := AnOwner;
FSubTreeCount := 1;
FIndex := -1;
FVisible := True;
if Owner<>nil then inc(Owner.FCount);
end;
@ -457,6 +458,16 @@ begin
Update;
end;
procedure TTreeNode.SetVisible(const AValue: Boolean);
begin
if FVisible = AValue then exit;
FVisible := AValue;
Selected := False;
if TreeView<>nil then
TreeView.FStates:=TreeView.FStates+[tvsScrollbarChanged,tvsTopsNeedsUpdate,tvsBottomItemNeedsUpdate, tvsTopItemNeedsUpdate];
Update;
end;
procedure TTreeNode.SetOverlayIndex(AValue: Integer);
begin
if FOverlayIndex = AValue then exit;
@ -805,18 +816,28 @@ end;
function TTreeNode.GetNextVisible: TTreeNode;
begin
if Expanded and (GetFirstChild<>nil) then
Result:=GetFirstChild
if FVisible and Expanded and (GetFirstVisibleChild<>nil) then
Result:=GetFirstVisibleChild
else begin
Result:=Self;
while (Result<>nil) and (Result.GetNextSibling=nil) do
while (Result<>nil) and (Result.GetNextVisibleSibling=nil) do
Result:=Result.Parent;
if Result<>nil then Result:=Result.GetNextSibling;
if Result<>nil then Result:=Result.GetNextVisibleSibling;
end;
if (Result<>nil) and (not Result.IsVisible) then
if (Result<>nil) and ((not Result.IsVisible) or (not Result.FVisible)) then
Result:=nil;
end;
function TTreeNode.GetNextVisibleSibling: TTreeNode;
begin
Result := Self;
repeat
Result := Result.GetNextSibling;
until ((Result=nil) or (Result.FVisible));
if (Result<>nil) and (not Result.FVisible) then
Result := nil
end;
function TTreeNode.GetPrevVisible: TTreeNode;
var
ANode: TTreeNode;
@ -896,6 +917,13 @@ begin
Result:=nil;
end;
function TTreeNode.GetFirstVisibleChild: TTreeNode;
begin
Result := GetFirstChild;
if (Result<>nil) and (not Result.FVisible) then
Result := Result.GetNextVisibleSibling;
end;
function TTreeNode.GetLastSibling: TTreeNode;
begin
if Parent<>nil then
@ -2915,7 +2943,7 @@ var
begin
//DebugLn(['TCustomTreeView.BeginEditing tvsIsEditing=',tvsIsEditing in FStates,' Selected=',Selected<>nil]);
if (tvsIsEditing in FStates) or (ANode=nil) then exit;
if not CanEdit(ANode) then exit;
if (not CanEdit(ANode)) or (not ANode.FVisible) then exit;
// if we are asked to edit another node while one is already being edited then
// stop editing that node
if FEditingItem <> nil then
@ -3160,10 +3188,12 @@ procedure TCustomTreeView.UpdateAllTops;
procedure CalculateTops(FirstSibling: TTreeNode; var CurTop: integer);
begin
while FirstSibling<>nil do begin
FirstSibling.fTop:=CurTop;
inc(CurTop,FirstSibling.Height);
if FirstSibling.Expanded then
CalculateTops(FirstSibling.GetFirstChild,CurTop);
if FirstSibling.FVisible then begin;
FirstSibling.fTop:=CurTop;
inc(CurTop,FirstSibling.Height);
if FirstSibling.Expanded then
CalculateTops(FirstSibling.GetFirstChild,CurTop);
end;
FirstSibling:=FirstSibling.GetNextSibling;
end;
end;
@ -3615,7 +3645,7 @@ end;
function TCustomTreeView.IsNodeVisible(ANode: TTreeNode): Boolean;
begin
Result:=(ANode<>nil) and (ANode.AreParentsExpanded);
Result:=(ANode<>nil) and (ANode.Visible) and (ANode.AreParentsExpanded);
//DebugLn('[TCustomTreeView.IsNodeVisible] A Node=',DbgS(ANode),
//' ANode.AreParentsExpanded=',ANode.AreParentsExpanded);
if Result then begin
@ -4209,7 +4239,8 @@ begin
//if Node<>nil then DebugLn(' Node.Text=',Node.Text) else DebugLn('');
while Node <> nil do
begin
DoPaintNode(Node);
if Node.Visible then
DoPaintNode(Node);
Node := Node.GetNextVisible;
//write('[TCustomTreeView.DoPaint] B Node=',DbgS(Node));
//if Node<>nil then DebugLn(' Node.Text=',Node.Text) else DebugLn('');
@ -4352,7 +4383,7 @@ var
DrawHorzLine(VertMid, CurMid, Result + Indent);
end;
if (CurNode.GetNextSibling <> nil) then
if (CurNode.GetNextVisibleSibling <> nil) then
begin
// draw vertical line to next brother
if (CurNode = Node) and HasExpandSign then