@@ -28067,25 +28067,73 @@ function TBaseVirtualTree.GetLastVisibleNoInit(Node: PVirtualNode = nil;
2806728067 ConsiderChildrenAbove: Boolean = True; IncludeFiltered: Boolean = False): PVirtualNode;
2806828068
2806928069// Returns the very last visible node in the tree while optionally considering toChildrenAbove.
28070+ // Note that the visibility of all ancestor nodes of the resulting node must not be considered.
2807028071// No initialization is performed.
28071- var
28072- Next: PVirtualNode;
2807328072
28074- begin
28075- Result := GetLastVisibleChildNoInit(Node, IncludeFiltered);
28076- if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.PaintOptions) then
28077- while Assigned(Result) and (vsExpanded in Result.States) do
28073+ //--------------- local functions -------------------------------------------
28074+
28075+ function GetNodeIsVisible(ChildNode: PVirtualNode): Boolean;
28076+ begin
28077+ Result := (vsVisible in ChildNode.States) and
28078+ (IncludeFiltered or not IsEffectivelyFiltered[ChildNode]);
28079+ end;
28080+
28081+ function GetNodeHasVisibleChildren(ChildNode: PVirtualNode): Boolean;
28082+ begin
28083+ Result := (vsHasChildren in ChildNode.States) and
28084+ (vsExpanded in ChildNode.States) and
28085+ not (vsAllChildrenHidden in ChildNode.States);
28086+ end;
28087+
28088+ function IterateChildren(ParentNode: PVirtualNode): PVirtualNode;
28089+ var
28090+ Run: PVirtualNode;
28091+ begin
28092+ Result := nil;
28093+
28094+ Run := GetLastChildNoInit(ParentNode); // Do not use 'GetLastVisibleChildNoInit' here (see above).
28095+ while Assigned(Run) do
2807828096 begin
28079- // Test if there is a next last child. If not keep the node from the last run.
28080- // Otherwise use the next last child.
28081- Next := GetLastChildNoInit(Result);
28082- if Assigned(Next) and (not (vsVisible in Next.States) or
28083- (not IncludeFiltered and IsEffectivelyFiltered[Next])) then
28084- Next := GetPreviousVisibleSiblingNoInit(Next, IncludeFiltered);
28085- if Next = nil then
28086- Break;
28087- Result := Next;
28097+ if ConsiderChildrenAbove and (toChildrenAbove in FOptions.PaintOptions) then
28098+ begin
28099+ if GetNodeIsVisible(Run) then
28100+ Result := Run
28101+ else if GetNodeHasVisibleChildren(Run) then
28102+ Result := IterateChildren(Run);
28103+ end else
28104+ begin
28105+ if GetNodeHasVisibleChildren(Run) then
28106+ Result := IterateChildren(Run)
28107+ else if GetNodeIsVisible(Run) then
28108+ Result := Run;
28109+ end;
28110+
28111+ if Assigned(Result) then
28112+ break;
28113+
28114+ Run := GetPreviousSiblingNoInit(Run);
2808828115 end;
28116+ end;
28117+
28118+ //--------------- end local functions ---------------------------------------
28119+
28120+ var
28121+ Run: PVirtualNode;
28122+
28123+ begin
28124+ Result := nil;
28125+
28126+ // First, check wether the given node and all its parents are expanded.
28127+ // If not, there can not be any visible child node.
28128+ Run := Node;
28129+ while Assigned(Run) and (Run <> RootNode) do
28130+ begin
28131+ if not (vsExpanded in Run.States) then
28132+ exit;
28133+ Run := Run.Parent;
28134+ end;
28135+
28136+ Result := IterateChildren(Node);
2808928137end;
2809028138
2809128139//----------------------------------------------------------------------------------------------------------------------
0 commit comments