cxgridstructurenavigator.pas

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

PAS
1,891
字号
  var
    I: Integer;
    AMenuItem: TMenuItem;
  begin
    FPopupMenuView := AView;
    Result := CreateViewMenuProvider(AView);
    if Result = nil then Exit;
    for I := 0 to Result.Items.Count - 1 do
    begin
      AMenuItem := CreateMenuItem(FPopupMenu, '');
      Result.Items[I].Prepare(AMenuItem);
      FPopupMenu.Items.Add(AMenuItem);
    end;
  end;

var
  AHitInfo: TcxGridStructureControlHitInfo;
  P: TPoint;
begin
  if Button <> mbRight then Exit;
  P := Point(X, Y);
  AHitInfo := FStructureControl.GetHitInfo(P);
  if AHitInfo.HitTest <> htNowhere then
  begin
    if FPopupMenu = nil then
      FPopupMenu := TPopupMenu.Create(nil);
    while FPopupMenu.Items.Count > 0 do
      FPopupMenu.Items[0].Free;

    FPopupMenuLevel := FStructureControl.GetLevelByRowIndex(AHitInfo.RowIndex);
    if FPopupMenuLevel <> nil then
    begin
      if FPopupMenuLevel.IsRoot then
        PrepareGridMenu
      else
        if AHitInfo.HitTest = htLevel then
          PrepareLevelMenu
        else
        begin
          FViewMenuProvider.Free;
          FViewMenuProvider := PrepareViewMenu(FPopupMenuLevel.GridView);
        end;
      P := FStructureControl.ClientToScreen(P);
      FPopupMenu.Popup(P.X, P.Y);
      FStructureControl.CancelPressed(Point(-1, -1));
    end;
  end;
end;

procedure TcxGridStructureHelper.UpdateDesigner;
begin
  if Assigned(FOnUpdateDesigner) then
    FOnUpdateDesigner(Self);
end;

procedure TcxGridStructureHelper.CreateLevelClick(Sender: TObject);
var
  ALevel: TcxGridLevel;
begin
  StructureControl.BeginUpdate;
  try
    ALevel := FPopupMenuLevel.Add;
    ALevel.Name := GenLevelName(StructureControl.Grid, ALevel);
    StructureControl.SelectComponent(ALevel);
    UpdateDesigner;
  finally
    StructureControl.EndUpdate;
  end;
end;

procedure TcxGridStructureHelper.CreateViewClick(Sender: TObject);
var
  AViewClass: TcxCustomGridViewClass;
  AView: TcxCustomGridView;
begin
  AViewClass := TcxCustomGridViewClass(
    cxGridRegisteredViews[((Sender as TMenuItem).Tag)]);
  StructureControl.BeginUpdate;
  try
    AView := StructureControl.Grid.CreateView(AViewClass);
    AView.Name := GenViewName(StructureControl.Grid, AView);
    RestoreViewFromTemplate(GetViewTemplateRegKey, AView);
    FPopupMenuLevel.GridView := AView;
    StructureControl.SelectComponent(AView);
    UpdateDesigner;
  finally
    StructureControl.EndUpdate;
  end;
end;

procedure TcxGridStructureHelper.SelectViewClick(Sender: TObject);
begin
  ExecuteLevelViewsMenuItem(FPopupMenuLevel, Sender as TMenuItem);
end;

procedure TcxGridStructureHelper.DeleteLevelClick(Sender: TObject);
begin
  StructureControl.BeginUpdate;
  try
    StructureControl.SelectComponent(FPopupMenuLevel.GetParentComponent);
    FPopupMenuLevel.Free;
    UpdateDesigner;
  finally
    StructureControl.EndUpdate;
  end;
end;

procedure TcxGridStructureHelper.MoveLevelClick(Sender: TObject);
var
  ASelection: TList;
begin
  ASelection := TList.Create;
  try
    StructureControl.GetSelection(ASelection);
    FPopupMenuLevel.Index := FPopupMenuLevel.Index + Integer(TMenuItem(Sender).Tag);
    UpdateDesigner;
    StructureControl.SyncSelection(ASelection);
  finally
    ASelection.Free;
  end;
end;

{ TcxGridStructureNavigator }

constructor TcxGridStructureNavigator.Create(AGrid: TcxCustomGrid);
begin
  inherited;
  FMakeSelectionVisible := True;
  FStructureControl := TcxGridStructureControl.Create(Self);
  with FStructureControl do
  begin
    SetBounds(0, 0, 0, 0);
    Grid := Self.Grid;
  {$IFDEF DELPHI6}
    MultiSelect := True;
  {$ENDIF}
    OnDrawBackground := DrawStructureControlBackground;
    OnSelectComponent := Self.SelectComponent;
    Parent := Self;
  end;
  FStructureHelper := TcxGridStructureHelper.Create(FStructureControl);
  FStructureHelper.OnUpdateDesigner := UpdateDesigner;
  FCloseButton := TSpeedButton.Create(Self);
  with FCloseButton do
  begin
    CreateCloseBitmap(Glyph);
    Flat := True;
    SetBounds(0, 0, 0, 0);
    OnClick := CloseButtonClick;
    Parent := Self;
  end;
  FCustomizeButton := TSpeedButton.Create(Self);
  with FCustomizeButton do
  begin
    Caption := SCustomizeText;
    Flat := True;
    SetBounds(0, 0, 0, 0);
    OnClick := CustomizeButtonClick;
    Parent := Self;
  end;
  FSeparator := TBevel.Create(Self);
  with FSeparator do
  begin
    Shape := bsTopLine;
    SetBounds(0, 0, 0, 0);
    Parent := Self;
  end;
  CreateDefaultComponents;
  FDesignHelper := TcxDesignHelper.Create(Grid);
{$IFDEF DELPHI6}
  DesignNotificationHandler.RegisterGrid(Grid);
{$ENDIF}
end;

destructor TcxGridStructureNavigator.Destroy;
begin
{$IFDEF DELPHI6}
  DesignNotificationHandler.UnregisterGrid(Grid);
{$ENDIF}
  FreeAndNil(FDesignHelper);
  FreeAndNil(FStructureHelper);
  inherited Destroy;
end;

procedure TcxGridStructureNavigator.Paint;
begin
  // Border
  Canvas.FrameRect(ClientRect, clWindowFrame, FrameBorderSize);
  // Background
  DrawBackground(Canvas);
end;

(*
procedure TcxGridStructureNavigator.Calculate;
var
  R: TRect;
  ACanvas: TcxCanvas;
  ACloseButtonSize: TSize;
  ACloseButtonArea: TRect;
  ACustomizeButtonArea: TRect;
  ASeparatorArea: TRect;
  ASeparatorHeight: Integer;
begin
  FStructureControl.ViewInfo.Calculate;
  R := FStructureControl.ViewInfo.Bounds;
  OffsetRect(R, FrameBorderSize, FrameBorderSize);
  FStructureControl.BoundsRect := R;
  // Calc Customize Button
  ASeparatorHeight := ButtonOffset * 2;
  ACanvas := FStructureControl.ViewInfo.Canvas;
  ACanvas.Font := FCustomizeButton.Font;
  ACloseButtonSize.cx := 2 * TextOffset + ACanvas.TextWidth(SCustomizeText) + 2 * ButtonBorderSize;
  ACloseButtonSize.cy := 2 * TextOffset + ACanvas.TextHeight(SCustomizeText) + 2 * ButtonBorderSize;
  ACustomizeButtonArea := Rect(R.Left, R.Bottom + ASeparatorHeight, R.Left + 2 * ButtonOffset + ACloseButtonSize.cx,
    R.Bottom + ASeparatorHeight + 2 * ButtonOffset + ACloseButtonSize.cy);
  FCustomizeButton.SetBounds(ACustomizeButtonArea.Left + ButtonOffset,
    ACustomizeButtonArea.Top + ButtonOffset, ACloseButtonSize.cx, ACloseButtonSize.cy);
  ASeparatorArea := Rect(ACustomizeButtonArea.Left, ACustomizeButtonArea.Top - ASeparatorHeight,
    ACustomizeButtonArea.Right, ACustomizeButtonArea.Top);
  if R.Right < ACustomizeButtonArea.Right then
    R.Right := ACustomizeButtonArea.Right;
  FSeparator.BoundsRect := Rect(ASeparatorArea.Left + ButtonOffset,
    ASeparatorArea.Top + ButtonOffset, R.Right - ButtonOffset,
    ASeparatorArea.Bottom);
  // Calc Close Button
  ACloseButtonArea := Rect(R.Right, R.Top,
    R.Right + 2 * ButtonOffset + CloseButtonWidth + 2 * ButtonBorderSize,
    R.Top + 2 * ButtonOffset + CloseButtonHeight + 2 * ButtonBorderSize);
  FCloseButton.SetBounds(ACloseButtonArea.Left + ButtonOffset,
    ACloseButtonArea.Top + ButtonOffset, CloseButtonWidth + 2 * ButtonBorderSize,
    CloseButtonHeight + 2 * ButtonBorderSize);
  if R.Bottom < ACloseButtonArea.Bottom then
    R.Bottom := ACloseButtonArea.Bottom;
  // Total Area
  R.Right := ACloseButtonArea.Right;
  R.Bottom := ACustomizeButtonArea.Bottom;
  InflateRect(R, FrameBorderSize, FrameBorderSize);
  SetBounds(Left, Top, R.Right - R.Left, R.Bottom - R.Top);
end;
*)

procedure TcxGridStructureNavigator.Calculate;
var
  R: TRect;
  ACanvas: TcxCanvas;
  ACloseButtonSize: TSize;
//  ACloseButtonArea: TRect;
  ACustomizeButtonArea: TRect;
  ASeparatorArea: TRect;
  ASeparatorHeight: Integer;
begin
  FStructureControl.ViewInfo.Calculate;
  R := FStructureControl.ViewInfo.Bounds;
  OffsetRect(R, FrameBorderSize, FrameBorderSize);
  FStructureControl.BoundsRect := R;
  // Calc Customize Button
  ASeparatorHeight := ButtonOffset * 2;
  ACanvas := FStructureControl.ViewInfo.Canvas;
  ACanvas.Font := FCustomizeButton.Font;
  ACloseButtonSize.cx := 2 * TextOffset + ACanvas.TextWidth(SCustomizeText) + 2 * ButtonBorderSize;
  ACloseButtonSize.cy := 2 * TextOffset + ACanvas.TextHeight(SCustomizeText) + 2 * ButtonBorderSize;
  ACustomizeButtonArea := Rect(R.Left, R.Bottom + ASeparatorHeight, R.Left + 2 * ButtonOffset + ACloseButtonSize.cx,
    R.Bottom + ASeparatorHeight + 2 * ButtonOffset + ACloseButtonSize.cy);
  FCustomizeButton.SetBounds(ACustomizeButtonArea.Left + ButtonOffset,
    ACustomizeButtonArea.Top + ButtonOffset, ACloseButtonSize.cx, ACloseButtonSize.cy);
  ASeparatorArea := Rect(ACustomizeButtonArea.Left, ACustomizeButtonArea.Top - ASeparatorHeight,
    ACustomizeButtonArea.Right, ACustomizeButtonArea.Top);
  if R.Right < ACustomizeButtonArea.Right then
    R.Right := ACustomizeButtonArea.Right;
  FSeparator.BoundsRect := Rect(ASeparatorArea.Left + ButtonOffset,
    ASeparatorArea.Top + ButtonOffset, R.Right - ButtonOffset,
    ASeparatorArea.Bottom);
  {// Calc Close Button
  ACloseButtonArea := Rect(R.Right, R.Top,
    R.Right + 2 * ButtonOffset + CloseButtonWidth + 2 * ButtonBorderSize,
    R.Top + 2 * ButtonOffset + CloseButtonHeight + 2 * ButtonBorderSize);
  FCloseButton.SetBounds(ACloseButtonArea.Left + ButtonOffset,
    ACloseButtonArea.Top + ButtonOffset, CloseButtonWidth + 2 * ButtonBorderSize,
    CloseButtonHeight + 2 * ButtonBorderSize);
  if R.Bottom < ACloseButtonArea.Bottom then
    R.Bottom := ACloseButtonArea.Bottom;
  // Total Area
  R.Right := ACloseButtonArea.Right;
  }
  R.Bottom := ACustomizeButtonArea.Bottom;
  InflateRect(R, FrameBorderSize, FrameBorderSize);
  SetBounds(Left, Top, R.Right - R.Left, R.Bottom - R.Top);
end;

function TcxGridStructureNavigator.CalculateBoundsRect: TRect;
begin
  Result := Rect(0, 0, Width, Height);
  OffsetRect(Result, Grid.ClientBounds.Right - Result.Right - NavigatorOffset,
    Grid.ClientBounds.Bottom - Result.Bottom - NavigatorOffset);
end;

procedure TcxGridStructureNavigator.Changed;
begin
  if FStructureControl = nil then Exit;
  Calculate;
  inherited Changed;
  FStructureControl.Invalidate;
  NotifyEditors;
end;

procedure TcxGridStructureNavigator.CreateDefaultComponents;
var
  AViewClass: TcxCustomGridViewClass;
begin
  if Grid.ViewCount <> 0 then Exit;
  AViewClass := GetDefaultViewClass;
  if AViewClass <> nil then
  begin
    FDefaultView := Grid.CreateView(AViewClass);
    FDefaultView.Name := GenViewName(Grid, FDefaultView);
    RestoreViewFromTemplate(GetViewTemplateRegKey, FDefaultView);
    // TODO: load default
    FDefaultLevel := Grid.Levels.Add;
    FDefaultLevel.Name := GenLevelName(Grid, FDefaultLevel);
    FDefaultLevel.GridView := FDefaultView;
  end;
end;

procedure TcxGridStructureNavigator.DrawBackground(ACanvas: TcxCanvas);
begin
  FillTubeGradientRect(ACanvas.Handle, ClientBounds, clWhite, {16248293}16115935{15785423}, False);
end;

procedure TcxGridStructureNavigator.DrawStructureControlBackground(Sender: TObject);
begin
  MoveWindowOrg(FStructureControl.Canvas.Handle, -FStructureControl.Left, -FStructureControl.Top);
  DrawBackground(FStructureControl.Canvas);
  MoveWindowOrg(FStructureControl.Canvas.Handle, FStructureControl.Left, FStructureControl.Top);
end;

function TcxGridStructureNavigator.GetClientBounds: TRect;
begin
  Result := inherited GetClientBounds;
  InflateRect(Result, -FrameBorderSize, -FrameBorderSize);
end;

function TcxGridStructureNavigator.GetDefaultViewClass: TcxCustomGridViewClass;
begin
  Result := TcxCustomGridAccess(Grid).GetDefaultViewClass;
  if Result = nil then
    Result := TcxGridDBTableView;
end;

function TcxGridStructureNavigator.GetDesigner: IDesigner;
begin
  Result := GetObjectDesigner(Grid);
end;

procedure TcxGridStructureNavigator.NotifyEditors;
var
  Msg: TMsg;
begin
  if not HandleAllocated then Exit;
  if not PeekMessage(Msg, Handle, CM_DeferUpdate, CM_DeferUpdate, PM_NOREMOVE) then
    PostMessage(Handle, CM_DeferUpdate, 0, 0);
end;

procedure TcxGridStructureNavigator.CloseButtonClick(Sender: TObject);
begin
  // TODO:
//  Visible := False;
end;

procedure TcxGridStructureNavigator.CustomizeButtonClick(Sender: TObject);
begin
  // TODO:
  if GetDesigner <> nil then
    ShowGridEditor(GetDesigner, Grid);
end;

procedure TcxGridStructureNavigator.SelectComponent(AObject: TPersistent;
  AClearSelection: Boolean);
begin
  if AClearSelection then
    FDesignHelper.SelectObject(AObject, True, False)
  else
    FDesignHelper.ChangeSelection(AObject);
end;

procedure TcxGridStructureNavigator.UpdateDesigner(Sender: TObject);
begin
  if GetDesigner <> nil then
    GetDesigner.Modified;
end;

procedure TcxGridStructureNavigator.CMDeferUpdate(var Message: TMessage);
begin
  UpdateDesignFormEditors(Grid);
end;

procedure TcxGridStructureNavigator.BeforeGridLoading;
begin
  FreeAndNil(FDefaultLevel);
  FreeAndNil(FDefaultView);
end;

function TcxGridStructureNavigator.IsObjectSelected(AObject: TPersistent): Boolean;
begin
  Result := FDesignHelper.IsObjectSelected(AObject);
end;

procedure TcxGridStructureNavigator.SelectionChanged(ASelection: TList);

  procedure MakeObjectVisible(AObject: TPersistent);
  begin
    //!!! columns/rows/bands/chartitems?
    if (AObject is TcxGridLevel) or (AObject is TcxCustomGridView) then
    begin
      if AObject is TcxCustomGridView then
        AObject := TcxCustomGridView(AObject).Level;
      if (AObject <> nil) and (TcxGridLevel(AObject).Control = Grid) then
        TcxGridLevel(AObject).MakeVisible;
    end;
  end;

begin
  if MakeSelectionVisible and (ASelection.Count = 1) then
    MakeObjectVisible(ASelection[0]);
  FStructureControl.SyncSelection(ASelection);
  if Grid.HandleAllocated then
    RedrawWindow(Grid.Handle, nil, 0, RDW_INVALIDATE or RDW_ALLCHILDREN);
end;

procedure TcxGridStructureNavigator.SelectObject(AObject: TPersistent;
  AClearSelection: Boolean);
begin
  MakeSelectionVisible := False;
  try
    SelectComponent(AObject, AClearSelection);
  finally
    MakeSelectionVisible := True;
  end;
end;

procedure TcxGridStructureNavigator.SelectObjects(AObjects: TList);
begin
  MakeSelectionVisible := False;
  try
    FDesignHelper.SetSelection(AObjects);
  finally
    MakeSelectionVisible := True;
  end;
end;

procedure TcxGridStructureNavigator.UnselectObject(AObject: TPersistent);
begin
  MakeSelectionVisible := False;
  try
    FDesignHelper.UnselectObject(AObject);
  finally
    MakeSelectionVisible := True;
  end;
end;

initialization
  cxGridStructureNavigatorClass := TcxGridStructureNavigator;
{$IFDEF DELPHI6}
  DesignNotificationHandler := TDesignNotificationHandler.Create;
{$ENDIF}

finalization
{$IFDEF DELPHI6}
  FreeAndNil(DesignNotificationHandler);
{$ENDIF}

end.

⌨️ 快捷键说明

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