Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

TElXTree cell alignment and more

Hi,
I'm trying to align text in all columns to right. Everything was done in design time. But the leftmost (main) tree column is always aligned to left. There is no way to change its behavior. And I've found this code portion:

ElXTreeCell.pas:

procedure TElXCustomTreeCell.AdjustTextRect
.................
  else
  begin
    //<abb2015>if Index <> LTree.MainTreeColumn then
    begin
      ATextRect.Right := Min(AR.Right - AR.Left, ATextRect.Right - ATextRect.Left) + AR.Left;
      ATextRect.Left := AR.Left;
    end
    {<abb2015>
    else
    begin
      ATextRect.Right := Min(AItemWholeRect.Right - AItemWholeRect.Left, ATextRect.Right - ATextRect.Left) + AItemWholeRect.Left;
      ATextRect.Left := AItemWholeRect.Left;
    end;
    </abb2015>}
  end;
..............
The problem is fixed after the changes, pointed above. But I'm not understanding the overall code. What is it for? What's the goal of such differentiation between main tree column and other columns here? Shouldn't you consider all columns as equitable, if ShowColumns is set?

Another issue appears after the changes above - the cell editor (float spinedit) has incorrect size - it is not of column width, but of text width! Looks like the rectangle, calculated above somehow is used for the cell editor...

Also this column is not selectable by mouse click, because of the code in TElXTreeView.GetItemAt():

  procedure GetIfNotRightAligned;
  .....................................
            if not Result.WholeLine and ((HitColumn <> FOwner.FMainTreeColumn) or Assigned(Result.Cells[FOwner.FMainTreeColumn].Control)) then
            begin
              LCell := Result.Cells[HitColumn].JointCellMaster;
              if Assigned(LCell) then
              begin
                Result := LCell.Owner;
                HitColumn := LCell.Index;
              end;
              if HitColumn = FOwner.FMainTreeColumn then
                ItemPart := ipMainText
              else
                ItemPart := ipColumn;
              Exit;
            end
            else
            begin
              ItemPart := ipInside;
              if Result.WholeLine then
                HitColumn := FOwner.MainTreeColumn;
              break;
            end;
................................
ItemPart := ipInside is returned, when the leftmost column is clicked. Therefore appropriate code in TElXTreeView.MouseDown() doesn't work:

    if ItemPart = ipColumn then
    begin
      ..........................
      ClickColumn;
      if FHeader.Sections[FHitColumn].ClickSelect then
          ......................
          LItem.DoSetSelected(True);

So, we also can see here that it's important (why?) if this is the main tree column or not. Why not to return
ItemPart := ipColumn always? I have in mind that "always" means "when ShowColumns is set"?

Can you explain it and fix the bug with alignment?

thank you.

P.S.
I came to the frustrating conclusion after some extra investigation - you use TElXTreeItem.FTextRect for both text drawing and other item parts location calculation... It's completely wrong approach, which doesn't allow to draw right-aligned text in the main tree column. Formally allowing to set horizontal alignment you really prohibit it for the main tree column. Otherwise all other item parts like plus/minus and checkbox will be aligned together with main column text, what is completely wrong.

Instead you must calculate item parts location independently from item text, only using item indentation and item nesting level.

Particularly I've fixed wrong cell editor width, pointed above by this patch:
procedure TElXTreeView.DoEditItem()
.........................
      else
      begin
        if FSectionNum = FOwner.FMainTreeColumn then //<abb2015>
        begin
          if FOwner.ShowColumns then
          begin
            Left := Cell.Left + 1;
            Right := Cell.Left + Cell.Width;
            TextWidth := Cell.Width;
          end                   else
          begin
            Left := FEditingItem.FTextRect.Left;
            Right := FEditingItem.FTextRect.Right;
            TextWidth := Right - Left;
          end;
        end
        else
....................................
But this patch is very ugly, and it works only for tree with columns. And I don't see a good idea, because the problem reason is covered very deeply in your code ideology.

PPS
I'd think about to rewrite painting procedure, e.g. TElXCustomTreeCell.DrawCellTextLocal() and its inner procedures, where FTextRect is assigned. Probably this is the most simple way to go.

Comments

  • 2 Comments sorted by Votes Date Added
  • Is fixed by the drawing procedure patching.
    Works for non-html output. Never checked this bug with html-formatted text.
    The fixes are sent to support.

    Hope this fix will appear in the next release!

Sign In or Register to comment.