cxgridstructurenavigator.pas

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

PAS
1,891
字号
procedure TcxGridStructureControl.GetSelectionLevels(ASelectionList: TList);
var
  I: Integer;
begin
  GetSelection(ASelectionList);
  for I := ASelectionList.Count - 1 downto 0 do
    if not (TObject(ASelectionList[I]) is TcxGridLevel) then
      ASelectionList.Delete(I);
end;

function TcxGridStructureControl.GetSelectionLevelCount: Integer;
var
  ASelectionList: TList;
begin
  ASelectionList := TList.Create;
  try
    GetSelectionLevels(ASelectionList);
    Result := ASelectionList.Count;
  finally
    ASelectionList.Free;
  end;
end;

procedure TcxGridStructureControl.GetSelectionViews(ASelectionList: TList);
var
  I: Integer;
begin
  GetSelection(ASelectionList);
  for I := ASelectionList.Count - 1 downto 0 do
    if not (TObject(ASelectionList[I]) is TcxCustomGridView) then
      ASelectionList.Delete(I);
end;

function TcxGridStructureControl.GetSelectionViewCount: Integer;
var
  ASelectionList: TList;
begin
  ASelectionList := TList.Create;
  try
    GetSelectionViews(ASelectionList);
    Result := ASelectionList.Count;
  finally
    ASelectionList.Free;
  end;
end;

procedure TcxGridStructureControl.SyncSelection(ASelectionList: TList);

  procedure CheckLevel(ARow: TcxGridStructureControlRowViewInfo; AComponent: TComponent);
  var
    ASelected: Boolean;
  begin
    ASelected := ASelectionList.IndexOf(AComponent) <> -1;
    if ARow.LevelSelected <> ASelected then
    begin
      ARow.LevelSelected := ASelected;
      InvalidateRect(ARow.LevelBounds, False);
    end;
  end;

  procedure CheckView(ARow: TcxGridStructureControlRowViewInfo; AComponent: TComponent);
  var
    ASelected: Boolean;
  begin
    ASelected := ASelectionList.IndexOf(AComponent) <> -1;
    if ARow.ViewSelected <> ASelected then
    begin
      ARow.ViewSelected := ASelected;
      InvalidateRect(ARow.ViewBounds, False);
    end;
  end;

var
  I: Integer;
  ALevel: TcxGridLevel;
begin
  for I := 0 to ViewInfo.Rows.Count - 1 do
  begin
    ALevel := ViewInfo.GetLevelByIndex(I);
    if Assigned(ALevel) then
      if ALevel.IsRoot then // TODO: IsRoot
        CheckLevel(ViewInfo.Rows[I], Grid)
      else
      begin
        CheckLevel(ViewInfo.Rows[I], ALevel);
        if ALevel.GridView <> nil then
          CheckView(ViewInfo.Rows[I], ALevel.GridView);
      end;
  end;
end;

procedure TcxGridStructureControl.MouseDown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
var
  AComponent: TComponent;
begin
  FMouseDownHitInfo := GetHitInfo(Point(X, Y));
  if Button in [mbLeft, mbRight] then
  begin
    AComponent := GetComponentByHitInfo(FMouseDownHitInfo);
    if AComponent <> nil then
      SelectComponent(AComponent, (Button = mbRight) or not MultiSelect or not (ssShift in Shift));
    SetPressed(True);
    CheckMousePos(Point(X, Y));
  end;
  inherited;
end;

procedure TcxGridStructureControl.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
  inherited;
  CheckMousePos(Point(X, Y));
end;

procedure TcxGridStructureControl.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited;
  if Button in [mbLeft, mbRight] then
    CancelPressed(Point(X, Y));
end;

procedure TcxGridStructureControl.Paint;
begin
  ViewInfo.Paint;
end;

procedure TcxGridStructureControl.AddToSelection(AObject: TPersistent; AClearSelection: Boolean);

  function IsEquals(AList1, AList2: TList): Boolean;
  var
    I: Integer;
  begin
    Result := AList1.Count = AList2.Count;
    if Result then
      for I := 0 to AList1.Count - 1 do
        if AList1[I] <> AList2[I] then
        begin
          Result := False;
          Break;
        end;
  end;

var
  APrevSelection, ASelection: TList;
begin
  APrevSelection := TList.Create;
  ASelection := TList.Create;
  try
    GetSelection(APrevSelection);
    if not AClearSelection then
      GetSelection(ASelection);
    if (AObject <> nil) and (ASelection.Remove(AObject) = -1) then
      ASelection.Add(AObject);
    if not IsEquals(ASelection, APrevSelection) then
    begin
      SyncSelection(ASelection);
      SelectionChanged;
    end;
  finally
    ASelection.Free;
    APrevSelection.Free;
  end;
end;

procedure TcxGridStructureControl.CancelPressed(P: TPoint);
begin
  SetPressed(False);
  CheckMousePos(P);
end;

procedure TcxGridStructureControl.CheckMousePos(P: TPoint);
begin
  FHitInfo := GetHitInfo(P);
  UpdateHighlighted;
end;

procedure TcxGridStructureControl.BoundsChanged;
begin
  inherited;
  Changed;
end;

procedure TcxGridStructureControl.DoDrawBackground;
begin
  if Assigned(FOnDrawBackground) then
    FOnDrawBackground(Self)
  else
  begin
    Canvas.Brush.Color := ViewInfo.GetContentColor;
    Canvas.FillRect(ClientRect);
  end;  
end;

procedure TcxGridStructureControl.FontChanged;
begin
  inherited;
  Changed;
end;

function TcxGridStructureControl.GetComponentByHitInfo(AHitInfo: TcxGridStructureControlHitInfo): TComponent;
var
  ALevel: TcxGridLevel;
begin
  Result := nil;
  if AHitInfo.RowIndex = -1 then Exit;
  ALevel := ViewInfo.GetLevelByIndex(AHitInfo.RowIndex);
  if ALevel = nil then Exit;
  if AHitInfo.HitTest = htLevel then
  begin
    if ALevel.IsRoot then // TODO
      Result := Grid
    else
      Result := ALevel;
  end
  else
    if AHitInfo.HitTest = htView then
    begin
      if ALevel.GridView <> nil then
        Result := ALevel.GridView;
    end;
end;

function TcxGridStructureControl.GetCursor(X, Y: Integer): TCursor;
begin
  if GetHitInfo(Point(X, Y)).HitTest in [htLevel, htView] then
    Result := crcxHandPoint
  else
    Result := inherited GetCursor(X, Y);
end;

function TcxGridStructureControl.MayFocus: Boolean;
begin
  Result := FMayFocused;
end;

procedure TcxGridStructureControl.MouseLeave(AControl: TControl);
begin
  CheckMousePos(Point(-1, -1));
end;

procedure TcxGridStructureControl.SelectComponent(AObject: TPersistent;
  AClearSelection: Boolean = True);
begin
{$IFNDEF DELPHI6}
  if not Assigned(FOnSelectComponent) then
{$ENDIF}
  AddToSelection(AObject, AClearSelection);
  if Assigned(FOnSelectComponent) then
    FOnSelectComponent(AObject, AClearSelection);
end;

procedure TcxGridStructureControl.SelectionChanged;
begin
  if Assigned(FOnSelectionChanged) then
    FOnSelectionChanged(Self);
end;

procedure TcxGridStructureControl.SetPressed(APressed: Boolean);
begin
  if FMousePressed <> APressed then
  begin
    FMousePressed := APressed;
    // TODO
  end;
end;

procedure TcxGridStructureControl.UpdateContent;
begin
  ViewInfo.Calculate;
  Invalidate;
end;

procedure TcxGridStructureControl.UpdateHighlighted;

  procedure CheckLevel(ARow: TcxGridStructureControlRowViewInfo; AHighlighted: Boolean);
  begin
    if ARow.LevelHighlighted <> AHighlighted then
    begin
      ARow.LevelHighlighted := AHighlighted;
      InvalidateRect(ARow.LevelBounds, False);
    end;
  end;

  procedure CheckView(ARow: TcxGridStructureControlRowViewInfo; AHighlighted: Boolean);
  begin
    if ARow.ViewHighlighted <> AHighlighted then
    begin
      ARow.ViewHighlighted := AHighlighted;
      InvalidateRect(ARow.ViewBounds, False);
    end;
  end;

var
  I: Integer;
  AHitInfo: TcxGridStructureControlHitInfo;
begin
  for I := 0 to ViewInfo.Rows.Count - 1 do
  begin
    if FMousePressed then
      AHitInfo := FMouseDownHitInfo
    else
      AHitInfo := FHitInfo;
    if AHitInfo.HitTest = htLevel then
    begin
      CheckLevel(ViewInfo.Rows[I], (AHitInfo.RowIndex = I));
      CheckView(ViewInfo.Rows[I], False);
    end
    else
      if AHitInfo.HitTest = htView then
      begin
        CheckLevel(ViewInfo.Rows[I], False);
        CheckView(ViewInfo.Rows[I], (AHitInfo.RowIndex = I));
      end
      else
      begin
        CheckLevel(ViewInfo.Rows[I], False);
        CheckView(ViewInfo.Rows[I], False);
      end;
  end;
end;

procedure TcxGridStructureControl.ClearSelection;
begin
  AddToSelection(nil, True);
end;

procedure TcxGridStructureControl.SetGrid(Value: TcxCustomGrid);
begin
  if FGrid <> Value then
  begin
    FGrid := Value;
    Changed;
  end;
end;

procedure TcxGridStructureControl.SetMultiSelect(Value: Boolean);
begin
  if FMultiSelect <> Value then
  begin
    FMultiSelect := Value;
    ClearSelection;
  end;
end;

{ TcxGridLevelViewList }

constructor TcxGridLevelViewList.Create(ALevel: TcxGridLevel);
begin
  FLevel := ALevel;
  inherited Create(GetObjectDesigner(ALevel));
end;

procedure TcxGridLevelViewList.GetViewNames;
var
  I: Integer;
  AView: TcxCustomGridView;
begin
  inherited;
  for I := ViewNames.Count - 1 downto 0 do
  begin
    AView := Views[I];
    if (AView.Repository = nil) and (AView.StorageControl <> Level.Control) then
      ViewNames.Delete(I);
  end;
end;

{ TcxGridStructureHelper }

constructor TcxGridStructureHelper.Create(AStructureControl: TcxGridStructureControl);
begin
  inherited Create;
  FStructureControl := AStructureControl;
  FStructureControl.OnMouseDown := StructureControlMouseDown;
end;

destructor TcxGridStructureHelper.Destroy;
begin
  FViewMenuProvider.Free;
  FreeAndNil(FPopupMenu);
  inherited Destroy;
end;

function TcxGridStructureHelper.CanAddComponent: Boolean;
begin
  Result := cxDesignWindows.CanAddComponent(StructureControl.Grid.Owner);
end;

function TcxGridStructureHelper.CanDeleteComponent(AComponent: TComponent): Boolean;
var
  AOwner: TComponent;
begin
  if AComponent = nil then
    AOwner := StructureControl.Grid.Owner
  else
    AOwner := AComponent.Owner;
  Result := cxDesignWindows.CanDeleteComponent(AOwner, AComponent);
end;

procedure TcxGridStructureHelper.ExecuteLevelViewsMenuItem(ALevel: TcxGridLevel; AMenuItem: TMenuItem);
var
  ALevelViewList: TcxGridLevelViewList;
  AView: TcxCustomGridView;
begin
  ALevelViewList := TcxGridLevelViewList.Create(ALevel);
  try
    AView := ALevelViewList.Views[AMenuItem.MenuIndex];
    if ALevel.GridView <> AView then
    begin
      ALevel.GridView := AView;
      UpdateDesigner;
    end;
  finally
    ALevelViewList.Free;
  end;
end;

procedure TcxGridStructureHelper.FillLevelViewsMenu(AMenu: TMenuItem;
  ALevel: TcxGridLevel; AOnClick: TNotifyEvent);
var
  ALevelViewList: TcxGridLevelViewList;
  I: Integer;
begin
  ALevelViewList := TcxGridLevelViewList.Create(ALevel);
  try
    for I := 0 to ALevelViewList.ViewNames.Count - 1 do
      AMenu.Add(CreateMenuItem(AMenu.Owner, ALevelViewList.ViewNames[I], AOnClick));
    if ALevel.GridView <> nil then
      AMenu[ALevelViewList.GetViewIndex(ALevel.GridView)].Checked := True;
  finally
    ALevelViewList.Free;
  end;
  AMenu.Add(CreateMenuItem(AMenu.Owner, '-'));
  AMenu.Add(CreateMenuItem(AMenu.Owner, 'None', AOnClick, True, -1, ALevel.GridView = nil));
end;

procedure TcxGridStructureHelper.StructureControlMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

  function IsViewEmpty(AView: TcxCustomGridView): Boolean;
  begin
    Result := AView.DataController.ItemCount = 0;
  end;

  procedure PrepareGridMenu;
  begin
    FPopupMenu.Items.Add(CreateMenuItem(FPopupMenu, 'Add Level', CreateLevelClick,
      CanAddComponent));
  end;

  procedure PrepareLevelMenu;
  var
    AMenuItem: TMenuItem;
  begin
    AMenuItem := CreateMenuItem(FPopupMenu, 'Create View', nil, CanAddComponent);
    FPopupMenu.Items.Add(AMenuItem);
    FillRegisteredViewsMenu(AMenuItem, CreateViewClick);

    AMenuItem := CreateMenuItem(FPopupMenu, 'Select View');
    FPopupMenu.Items.Add(AMenuItem);
    FillLevelViewsMenu(AMenuItem, FPopupMenuLevel, SelectViewClick);

    PrepareGridMenu;
    FPopupMenu.Items.Add(CreateMenuItem(FPopupMenu, '-'));
    FPopupMenu.Items.Add(CreateMenuItem(FPopupMenu, 'Delete Level',
      DeleteLevelClick, CanDeleteComponent(FPopupMenuLevel)));
    FPopupMenu.Items.Add(CreateMenuItem(FPopupMenu, '-'));
    FPopupMenu.Items.Add(CreateMenuItem(FPopupMenu, 'Move Level Up', MoveLevelClick,
      FPopupMenuLevel.Index > 0, -1));
    FPopupMenu.Items.Add(CreateMenuItem(FPopupMenu, 'Move Level Down', MoveLevelClick,
      FPopupMenuLevel.Index < FPopupMenuLevel.Parent.Count - 1, 1));
  end;

  function PrepareViewMenu(AView: TcxCustomGridView): TcxCustomGridViewMenuProvider;

⌨️ 快捷键说明

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