Skip to content

Issues with toHideSelection #789

Closed
Closed
@pyscripter

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)

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions