cxgridstructurenavigator.pas

来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,891 行 · 第 1/4 页

PAS
1,891
字号
  inherited Create;
  FStructureControl := AStructureControl;
  FRows := TcxGridStructureControlRowsViewInfo.Create;
end;

destructor TcxGridStructureControlViewInfo.Destroy;
begin
  FRows.Free;
  FreeAndNil(FCanvas);
  inherited Destroy;
end;

procedure TcxGridStructureControlViewInfo.Calculate;
var
  ASelection: TList;
  W, H: Integer;
  I, ALevelOffset, ATop: Integer;
  ARow: TcxGridStructureControlRowViewInfo;
begin
  // TODO: ref
  if Grid = nil then Exit;
  ASelection := TList.Create;
  try
    // save selection
    StructureControl.GetSelection(ASelection);
    // Init
    Canvas.Font := GetContentFont;
    FTextHeight := Canvas.TextHeight('Wg');
    FRowHeight := 2 * RowOffset + 2 * RowBorderWidth + 2 * TextOffset + FTextHeight;
    // Rows
    FRows.Clear;
    H := GetRowCount * FRowHeight;
    Bounds := Rect(0, 0, 0, H);
    ATop := 0;
    for I := 0 to GetRowCount - 1 do
    begin
      ARow := TcxGridStructureControlRowViewInfo.Create;
      GetLevelInfo(I, ARow.LevelText, ARow.ViewText, ARow.TreeLineVertCount,
        ARow.TreeLineIsParent, ARow.TreeLineIsLast);
      // Level
      ARow.LevelTextArea := Rect(0, ATop, Canvas.TextWidth(ARow.LevelText), ATop + FTextHeight);
      OffsetRect(ARow.LevelTextArea, TextOffset, TextOffset);
      ARow.LevelContentBounds := ARow.LevelTextArea;
      InflateRect(ARow.LevelContentBounds, TextOffset, TextOffset);
      OffsetRect(ARow.LevelTextArea, RowBorderWidth, RowBorderWidth);
      OffsetRect(ARow.LevelContentBounds, RowBorderWidth, RowBorderWidth);
      ARow.LevelBounds := ARow.LevelContentBounds;
      InflateRect(ARow.LevelBounds, RowBorderWidth, RowBorderWidth);
      ARow.Bounds := ARow.LevelBounds;
      OffsetRect(ARow.LevelBounds, RowOffset, RowOffset);
      OffsetRect(ARow.LevelContentBounds, RowOffset, RowOffset);
      OffsetRect(ARow.LevelTextArea, RowOffset, RowOffset);
      //InflateRect(ARow.Bounds, RowOffset, RowOffset);
      OffsetRect(ARow.Bounds, RowOffset, RowOffset);
      // Indent
      ALevelOffset := ARow.TreeLineVertCount * (LevelIndent + RowOffset);
      OffsetRect(ARow.LevelBounds, ALevelOffset, 0);
      OffsetRect(ARow.LevelContentBounds, ALevelOffset, 0);
      OffsetRect(ARow.LevelTextArea, ALevelOffset, 0);
      OffsetRect(ARow.Bounds, ALevelOffset, 0);
      // View
      if (I > 0) and (ARow.ViewText <> '') then
      begin
        W := 2 * RowBorderWidth + 2 * TextOffset + Canvas.TextWidth(ARow.ViewText);
        ARow.ViewBounds := Rect(ARow.LevelBounds.Right - RowBorderWidth, ARow.LevelBounds.Top,
          ARow.LevelBounds.Right - RowBorderWidth + W, ARow.LevelBounds.Bottom);
        ARow.ViewContentBounds := ARow.ViewBounds;
        InflateRect(ARow.ViewContentBounds, -RowBorderWidth, -RowBorderWidth);
        ARow.ViewTextArea := ARow.ViewContentBounds;
        InflateRect(ARow.ViewTextArea, -TextOffset, -TextOffset);
        Inc(ARow.Bounds.Right, W - RowBorderWidth);
      end;
      FRows.Add(ARow);
      Bounds.Right := Max(Bounds.Right, ARow.Bounds.Right + RowOffset);
      Inc(ATop, FRowHeight);
    end;
    Bounds.Bottom := ATop;
    // restore selection
    StructureControl.SyncSelection(ASelection);
  finally
    ASelection.Free;
  end;
end;

function TcxGridStructureControlViewInfo.GetContentColor: TColor;
begin
  Result := clWhite;
end;

function TcxGridStructureControlViewInfo.GetContentFont: TFont;
begin
  Result := StructureControl.Font;
end;

function TcxGridStructureControlViewInfo.GetContentFontColor: TColor;
begin
  Result := clBlack;
end;

function TcxGridStructureControlViewInfo.GetGridColor(AHighlighted: Boolean): TColor;
begin
  if AHighlighted then
    Result := cxGridDesignGridHotColor
  else
    Result := cxGridDesignGridColor;
end;

function TcxGridStructureControlViewInfo.GetHighlightedFontColor: TColor;
begin
  Result := GetContentFontColor;
end;

function TcxGridStructureControlViewInfo.GetLevelColor(AHighlighted: Boolean): TColor;
begin
  if AHighlighted then
    Result := cxGridDesignLevelHotColor
  else
    Result := cxGridDesignLevelColor;
end;

function TcxGridStructureControlViewInfo.GetRowBorderColor(AColorIndex: TcxGridColorIndex;
  ASelected, AHighlighted: Boolean): TColor;
begin
  if ASelected then
    if AHighlighted then
      Result := cxGridDesignSelectedHotBorderColor
    else
      Result := cxGridDesignSelectedBorderColor
  else
    case AColorIndex of
      ciLevel:
        if AHighlighted then
          Result := cxGridDesignLevelHotBorderColor
        else
          Result := cxGridDesignLevelBorderColor;
      ciView:
        Result := cxGridDesignViewBorderColor;
    else
      if AHighlighted then
        Result := cxGridDesignGridHotBorderColor
      else
        Result := cxGridDesignGridBorderColor;
    end;
end;

function TcxGridStructureControlViewInfo.GetRowColor(AColorIndex: TcxGridColorIndex;
  ASelected, AHighlighted: Boolean): TColor;
begin
  if ASelected then
    Result := GetSelectedColor(AHighlighted)
  else
    case AColorIndex of
      ciLevel:
        Result := GetLevelColor(AHighlighted);
      ciView:
        Result := GetViewColor(AHighlighted);
    else
      Result := GetGridColor(AHighlighted);
    end;
end;

function TcxGridStructureControlViewInfo.GetRowTextColor(AColorIndex: TcxGridColorIndex;
  ASelected, AHighlighted: Boolean): TColor;
begin
  if ASelected then
    Result := GetSelectedFontColor
  else
    if AHighlighted then
      Result := GetHighlightedFontColor
    else
      Result := GetContentFontColor;
end;

function TcxGridStructureControlViewInfo.GetSelectedColor(AHighlighted: Boolean): TColor;
begin
  if AHighlighted then
    Result := cxGridDesignSelectedHotColor
  else
    Result := cxGridDesignSelectedColor;
end;

function TcxGridStructureControlViewInfo.GetSelectedFontColor: TColor;
begin
  Result := GetContentFontColor;
end;

function TcxGridStructureControlViewInfo.GetViewColor(AHighlighted: Boolean): TColor;
begin
  if AHighlighted then
    Result := cxGridDesignViewHotColor
  else
    Result := cxGridDesignViewColor;
end;

procedure TcxGridStructureControlViewInfo.Paint;

  procedure SetFontAndBrush(ASelected, AHighlighted: Boolean; AColorIndex: TcxGridColorIndex);
  begin
    Canvas.Brush.Color := GetRealColor(GetRowColor(AColorIndex, ASelected, AHighlighted));
    Canvas.Font.Color := GetRealColor(GetRowTextColor(AColorIndex, ASelected, AHighlighted));
    {if AHighlighted then
      Canvas.Font.Style := Canvas.Font.Style + [fsUnderline]
    else
      Canvas.Font.Style := Canvas.Font.Style - [fsUnderline];}
  end;

  procedure DrawCell(ACellRect, ATextRect: TRect; const AText: string);
  begin
    Canvas.FillRect(ACellRect);
    Canvas.Brush.Style := bsClear;
    Canvas.DrawText(AText, ATextRect, cxAlignLeft or cxAlignVCenter or cxSingleLine);
    Canvas.Brush.Style := bsSolid;
  end;

  procedure DrawRows;
  var
    I: Integer;
    ARow: TcxGridStructureControlRowViewInfo;
    AColorIndex: TcxGridColorIndex;
  begin
    for I := 0 to Rows.Count - 1 do
    begin
      ARow := Rows[I];
      // Level
      if I = 0 then
        AColorIndex := ciGrid
      else
        AColorIndex := ciLevel;
      Canvas.FrameRect(ARow.LevelBounds,
        GetRealColor(GetRowBorderColor(AColorIndex, ARow.LevelSelected, ARow.LevelHighlighted)),
        RowBorderWidth);
      SetFontAndBrush(ARow.LevelSelected, ARow.LevelHighlighted, AColorIndex);
      DrawCell(ARow.LevelContentBounds, ARow.LevelTextArea, ARow.LevelText);
      // View
      if not IsRectEmpty(ARow.ViewBounds) then
      begin
        Canvas.FrameRect(ARow.ViewBounds,
          GetRealColor(GetRowBorderColor(ciView, ARow.ViewSelected, ARow.ViewHighlighted)),
          RowBorderWidth);
        SetFontAndBrush(ARow.ViewSelected, ARow.ViewHighlighted, ciView);
        DrawCell(ARow.ViewContentBounds, ARow.ViewTextArea, ARow.ViewText);
      end;
      Canvas.ExcludeClipRect(ARow.Bounds);
    end;
  end;

begin
  // Rows
  Canvas.Font := GetContentFont;
  DrawRows;
  // Background
  StructureControl.DoDrawBackground;
end;

function TcxGridStructureControlViewInfo.GetCanvas: TcxCanvas;
begin
  if StructureControl.HandleAllocated then
  begin
    if FCanvas <> nil then
      FreeAndNil(FCanvas);
    Result := StructureControl.Canvas;
  end
  else
  begin
    if FCanvas = nil then
      FCanvas := TcxScreenCanvas.Create;
    Result := FCanvas;
  end;
end;

function TcxGridStructureControlViewInfo.GetGrid: TcxCustomGrid;
begin
  Result := StructureControl.Grid;
end;

function TcxGridStructureControlViewInfo.GetLevelByIndex(AIndex: Integer): TcxGridLevel;
var
  ACurrent: Integer;

  procedure CalculateCount(ALevel: TcxGridLevel);
  var
    I: Integer;
  begin
    if ALevel = nil then Exit;
    if ACurrent = AIndex then
      Result := ALevel
    else
    begin
      Inc(ACurrent);
      for I := 0 to ALevel.Count - 1 do
      begin
        CalculateCount(ALevel[I]);
        if Result <> nil then
          Break;
      end;
    end;  
  end;

begin
  Result := nil;
  ACurrent := 0;
  if (Grid <> nil) and (Grid.Levels <> nil) then
    CalculateCount(Grid.Levels);
end;

procedure TcxGridStructureControlViewInfo.GetLevelInfo(AIndex: Integer;
  var ALevelText, AViewText: string; var ALevelIndex: Integer;
  var AIsParent, AIsLast: Boolean);

  function GetCompName(AComponent: TComponent): string;
  begin
    Result := AComponent.Name;
    if Result = '' then
      Result := '< >';
  end;

var
  ALevel: TcxGridLevel;
begin
  ALevelText := '';
  AViewText := '';
  ALevelIndex := 0;
  AIsParent := False;
  AIsLast := False;
  ALevel := GetLevelByIndex(AIndex);
  if ALevel <> nil then
  begin
    AIsParent := ALevel.Count > 0;
    AIsLast := (ALevel.Parent <> nil) and
      (ALevel.Parent[ALevel.Parent.Count - 1] = ALevel);
    if ALevel.IsRoot then // TODO: IsRoot
      ALevelText := GetCompName(Grid)
    else
    begin
      ALevelText := GetCompName(ALevel);
      if ALevel.GridView <> nil then
        AViewText := GetCompName(ALevel.GridView);
    end;
  end;
  ALevelIndex := 0;
  while ALevel <> nil do
  begin
    if ALevel.IsRoot then // TODO: IsRoot
      Break
    else
    begin
      Inc(ALevelIndex);
      ALevel := ALevel.Parent;
    end;
  end;
end;

function TcxGridStructureControlViewInfo.GetRowCount: Integer;

  procedure CalculateCount(ALevel: TcxGridLevel);
  var
    I: Integer;
  begin
    Inc(Result, ALevel.Count);
    for I := 0 to ALevel.Count - 1 do
      CalculateCount(ALevel[I]);
  end;

begin
  if Grid = nil then
    Result := 0
  else
  begin
    Result := 1; // Root
    if Grid.Levels <> nil then
      CalculateCount(Grid.Levels);
  end;    
end;

{ TcxGridStructureControl }

constructor TcxGridStructureControl.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FViewInfo := TcxGridStructureControlViewInfo.Create(Self);
end;

destructor TcxGridStructureControl.Destroy;
begin
  FreeAndNil(FViewInfo);
  inherited Destroy;
end;

procedure TcxGridStructureControl.BeginUpdate;
begin
  Inc(FLockCount);
end;

procedure TcxGridStructureControl.Changed;
begin
  if LockCount = 0 then
    UpdateContent;
end;

procedure TcxGridStructureControl.EndUpdate;
begin
  Dec(FLockCount);
  Changed;
end;

function TcxGridStructureControl.GetHitInfo(P: TPoint): TcxGridStructureControlHitInfo;
var
  I: Integer;
begin
  Result.HitTest := htNowhere;
  Result.RowIndex := -1;
  for I := 0 to ViewInfo.Rows.Count - 1 do
    if PtInRect(ViewInfo.Rows[I].Bounds, P) then
    begin
      Result.RowIndex := I;
      if PtInRect(ViewInfo.Rows[I].LevelBounds, P) then
      begin
        Result.HitTest := htLevel;
        Break;
      end
      else
        if PtInRect(ViewInfo.Rows[I].ViewBounds, P) then
        begin
          Result.HitTest := htView;
          Break;
        end;
    end;
end;

function TcxGridStructureControl.GetLevelByRowIndex(ARowIndex: Integer): TcxGridLevel;
begin
  Result := ViewInfo.GetLevelByIndex(ARowIndex);
end;

function TcxGridStructureControl.GetSelectedLevel: TcxGridLevel;
var
  ASelectionList: TList;
begin
  Result := nil;
  ASelectionList := TList.Create;
  try
    GetSelectionLevels(ASelectionList);
    if ASelectionList.Count = 1 then
      Result := TcxGridLevel(ASelectionList[0]);
  finally
    ASelectionList.Free;
  end;
end;

procedure TcxGridStructureControl.GetSelection(ASelectionList: TList);
var
  I: Integer;
  ALevel: TcxGridLevel;
begin
  ASelectionList.Clear;
  for I := 0 to ViewInfo.Rows.Count - 1 do
  begin
    ALevel := ViewInfo.GetLevelByIndex(I);
    if Assigned(ALevel) then
    begin
      if ViewInfo.Rows[I].LevelSelected then
      begin
        if ALevel.IsRoot then // TODO: IsRoot
          ASelectionList.Add(Grid)
        else
          ASelectionList.Add(ALevel);
      end;
      if ViewInfo.Rows[I].ViewSelected and (ALevel.GridView <> nil) then
        ASelectionList.Add(ALevel.GridView);
    end;
  end;
end;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?