Description
HideSelection is a property of many Delphi controls (TMemo, TListView, TTreeView ect.) and is True by default. I suggest that toHideSelection is added to DefaultPaintOptions.
The problem with toHideSelection is that it is not respected. The painting of an item as selected is controlled by the paint option poDrawSelection. poDrawSelection is correctly set in PaintTree as
if (toAlwaysHideSelection in FOptions.FPaintOptions) or
(not Focused and (toHideSelection in FOptions.FPaintOptions)) then
Exclude(PaintOptions, poDrawSelection);
So far, so good. However further down, PaintTree calls DoPaintNode, which calls PaintNormalText, which calls InitializeTextProperties, In that last procedure another check is made about whether the control is focused without considering toHideSelection. This second check is not needed and should be removed.
// 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
begin
if Node = FDropTargetNode then
begin
if ((FLastDropMode = dmOnNode) or (vsSelected in Node.States)) and not
(tsUseExplorerTheme in FStates) then
Canvas.Font.Color := FColors.SelectionTextColor;
end
else
if vsSelected in Node.States then
begin
if (Focused or (toPopupMode in FOptions.FPaintOptions)) and not //<-- Here is the problem
(tsUseExplorerTheme in FStates) then
Canvas.Font.Color := FColors.SelectionTextColor;
end;
end;
end;
There is another related issue. DoDrawBackground called by PaintTree correctly sets the background colors if paDrawSelection is in PaintOptions:
if Focused or (toPopupMode in FOptions.FPaintOptions) then
begin
Brush.Color := FColors.FocusedSelectionColor;
Pen.Color := FColors.FocusedSelectionBorderColor;
end
else
begin
Brush.Color := FColors.UnfocusedSelectionColor;
Pen.Color := FColors.UnfocusedSelectionBorderColor;
end;
The UnfocusedSelectionColor and UnfocusedSelectionBorderColor are only used for selected nodes that are not focused when toHideSelection is not present. But these colors correspond to the same colors as unselected nodes. Instead they should default to clHighlight.
Finally, GetColor has a few issues with VCL Styles enabled.
A: In code such as the one below GetElemenetColor does not touch result if it returns False and in the second condition Result is undetermined.
if not StyleServices.GetElementColor(StyleServices.GetElementDetails(ttItemHot), ecTextColor, Result) or
(Result <> clWindowText) then
Result := NodeFontColor;
B. Code such as this
if FColors[Index] = clHighlight then
Result := StyleServices.GetSystemColor(clHighlight)
else
Result := FColors[Index];
should be better written as
Result := StyleServices.GetSystemColor(FColors[Index]);
since if GetSystemColor(Color) returns Color if it is not a system color and when you use VCL styles and you specify a color as a system color you most likely want it converted to the corresponding color in the active style.
I have implemented the above changes in the attached file and you can review the changes with a diff viewer. If you prefer I can submit a diff file or a PR.
VirtualTrees.zip
(Please ignore and use the patch file below, which contains further refinements)