cxgridstructurenavigator.pas

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

PAS
1,891
字号
{********************************************************************}
{                                                                    }
{       Developer Express Visual Component Library                   }
{       ExpressQuantumGrid                                           }
{                                                                    }
{       Copyright (c) 1998-2008 Developer Express Inc.               }
{       ALL RIGHTS RESERVED                                          }
{                                                                    }
{   The entire contents of this file is protected by U.S. and        }
{   International Copyright Laws. Unauthorized reproduction,         }
{   reverse-engineering, and distribution of all or any portion of   }
{   the code contained in this file is strictly prohibited and may   }
{   result in severe civil and criminal penalties and will be        }
{   prosecuted to the maximum extent possible under the law.         }
{                                                                    }
{   RESTRICTIONS                                                     }
{                                                                    }
{   THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES            }
{   (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE     }
{   SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS    }
{   LICENSED TO DISTRIBUTE THE EXPRESSQUANTUMGRID AND ALL            }
{   ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
{                                                                    }
{   THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED       }
{   FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE         }
{   COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE        }
{   AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT   }
{   AND PERMISSION FROM DEVELOPER EXPRESS INC.                       }
{                                                                    }
{   CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON        }
{   ADDITIONAL RESTRICTIONS.                                         }
{                                                                    }
{********************************************************************}

unit cxGridStructureNavigator; // TODO transparency

{$I cxVer.inc}

interface

uses
{$IFDEF DELPHI6}
    DesignIntf,
{$ELSE}
  DsgnIntf,
{$ENDIF}
  Windows, Messages, TypInfo, Classes, SysUtils, Controls, Graphics, Forms,
  Menus, ExtCtrls, Buttons,
  cxControls, cxClasses, cxGraphics, cxDesignWindows,
  cxGridCommon, cxGrid, cxGridLevel, cxGridCustomView, cxViewEditor;

const
  CM_DeferUpdate = WM_DX + 25;

type
  TcxGridStructureControl = class;
  TcxGridStructureNavigator = class;

  TcxGridColorIndex = (ciGrid, ciLevel, ciView);

  { TcxGridStructureControlViewInfo }

  TcxGridStructureControlRowViewInfo = class
    Bounds: TRect;

    LevelBounds: TRect;
    LevelContentBounds: TRect;
    LevelHighlighted: Boolean;
    LevelSelected: Boolean;
    LevelText: string;
    LevelTextArea: TRect;

    ViewBounds: TRect;
    ViewContentBounds: TRect;
    ViewHighlighted: Boolean;
    ViewSelected: Boolean;
    ViewText: string;
    ViewTextArea: TRect;

    TreeLineVertCount: Integer;
    TreeLineIsParent: Boolean;
    TreeLineIsLast: Boolean;
  end;

  TcxGridStructureControlRowsViewInfo = class(TcxObjectList)
  private
    function GetItem(Index: Integer): TcxGridStructureControlRowViewInfo;
  public
    property Items[Index: Integer]: TcxGridStructureControlRowViewInfo read GetItem; default;
  end;

  TcxGridStructureControlViewInfo = class
  private
    FCanvas: TcxCanvas;
    FStructureControl: TcxGridStructureControl;
    FTextHeight: Integer;
    FRowHeight: Integer;
    FRows: TcxGridStructureControlRowsViewInfo;
    function GetCanvas: TcxCanvas;
    function GetGrid: TcxCustomGrid;
    function GetLevelByIndex(AIndex: Integer): TcxGridLevel;
    procedure GetLevelInfo(AIndex: Integer; var ALevelText, AViewText: string; var ALevelIndex: Integer; var AIsParent, AIsLast: Boolean);
    function GetRowCount: Integer;
  public
    Bounds: TRect;
    constructor Create(AStructureControl: TcxGridStructureControl);
    destructor Destroy; override;
    procedure Calculate;

    function GetContentColor: TColor;
    function GetContentFont: TFont;
    function GetContentFontColor: TColor;
    function GetGridColor(AHighlighted: Boolean): TColor;
    function GetHighlightedFontColor: TColor;
    function GetLevelColor(AHighlighted: Boolean): TColor;
    function GetRowBorderColor(AColorIndex: TcxGridColorIndex; ASelected, AHighlighted: Boolean): TColor;
    function GetRowColor(AColorIndex: TcxGridColorIndex; ASelected, AHighlighted: Boolean): TColor;
    function GetRowTextColor(AColorIndex: TcxGridColorIndex; ASelected, AHighlighted: Boolean): TColor;
    function GetSelectedColor(AHighlighted: Boolean): TColor;
    function GetSelectedFontColor: TColor;
    function GetViewColor(AHighlighted: Boolean): TColor;
    
    procedure Paint;

    property Canvas: TcxCanvas read GetCanvas;
    property Grid: TcxCustomGrid read GetGrid;
    property StructureControl: TcxGridStructureControl read FStructureControl;
    property Rows: TcxGridStructureControlRowsViewInfo read FRows;
  end;

  { TcxGridStructureControl }

  TcxGridStructureControlSelectComponentEvent = procedure(AObject: TPersistent;
    AClearSelection: Boolean) of object;

  TcxGridStructureControlHitTest = (htNowhere, htLevel, htView);

  TcxGridStructureControlHitInfo = record
    HitTest: TcxGridStructureControlHitTest;
    RowIndex: Integer;
  end;

  TcxGridStructureControl = class(TcxControl)
  private
    FGrid: TcxCustomGrid;
    FHitInfo: TcxGridStructureControlHitInfo;
    FLockCount: Integer;
    FMayFocused: Boolean;
    FMouseDownHitInfo: TcxGridStructureControlHitInfo;
    FMousePressed: Boolean;
    FMultiSelect: Boolean;
    FViewInfo: TcxGridStructureControlViewInfo;
    FOnDrawBackground: TNotifyEvent;
    FOnSelectComponent: TcxGridStructureControlSelectComponentEvent;
    FOnSelectionChanged: TNotifyEvent;
    procedure ClearSelection;
    procedure SetGrid(Value: TcxCustomGrid);
    procedure SetMultiSelect(Value: Boolean);
  protected
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure Paint; override;

    procedure AddToSelection(AObject: TPersistent; AClearSelection: Boolean);
    procedure CancelPressed(P: TPoint);
    procedure CheckMousePos(P: TPoint);
    procedure BoundsChanged; override;
    procedure DoDrawBackground; virtual;
    procedure FontChanged; override;
    function GetComponentByHitInfo(AHitInfo: TcxGridStructureControlHitInfo): TComponent;
    function GetCursor(X, Y: Integer): TCursor; override;
    function MayFocus: Boolean; override;
    procedure MouseLeave(AControl: TControl); override;
    procedure SelectComponent(AObject: TPersistent; AClearSelection: Boolean = True);
    procedure SelectionChanged; virtual;
    procedure SetPressed(APressed: Boolean);
    procedure UpdateContent; virtual;
    procedure UpdateHighlighted;
    property LockCount: Integer read FLockCount;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure BeginUpdate;
    procedure Changed;
    procedure EndUpdate;
    function GetHitInfo(P: TPoint): TcxGridStructureControlHitInfo;
    function GetLevelByRowIndex(ARowIndex: Integer): TcxGridLevel;
    function GetSelectedLevel: TcxGridLevel;
    procedure GetSelection(ASelectionList: TList);
    procedure GetSelectionLevels(ASelectionList: TList);
    function GetSelectionLevelCount: Integer;
//    function GetSelectedView: TcxCustomGridView;
    procedure GetSelectionViews(ASelectionList: TList);
    function GetSelectionViewCount: Integer;
    procedure SyncSelection(ASelectionList: TList);
    property Grid: TcxCustomGrid read FGrid write SetGrid;
    property Keys;
    property MayFocused: Boolean read FMayFocused write FMayFocused;
    property MultiSelect: Boolean read FMultiSelect write SetMultiSelect;
    property ViewInfo: TcxGridStructureControlViewInfo read FViewInfo;
    property OnKeyPress;
    property OnDrawBackground: TNotifyEvent read FOnDrawBackground write FOnDrawBackground;
    property OnSelectComponent: TcxGridStructureControlSelectComponentEvent read FOnSelectComponent write FOnSelectComponent;
    property OnSelectionChanged: TNotifyEvent read FOnSelectionChanged write FOnSelectionChanged;
  end;

  { TcxGridStructureHelper }

  TcxGridLevelViewList = class(TcxGridViewList)
  private
    FLevel: TcxGridLevel;
  protected
    procedure GetViewNames; override;
  public
    constructor Create(ALevel: TcxGridLevel);
    property Level: TcxGridLevel read FLevel;
  end;

  TcxGridStructureHelper = class
  private
    FPopupMenu: TPopupMenu;
    FPopupMenuLevel: TcxGridLevel;
    FStructureControl: TcxGridStructureControl;
    FOnUpdateDesigner: TNotifyEvent;
    procedure CreateLevelClick(Sender: TObject);
    procedure CreateViewClick(Sender: TObject);
    procedure SelectViewClick(Sender: TObject);
    procedure DeleteLevelClick(Sender: TObject);
    procedure MoveLevelClick(Sender: TObject);
  protected
    FPopupMenuView: TcxCustomGridView;
    FViewMenuProvider: TcxCustomGridViewMenuProvider;
    function CanAddComponent: Boolean;
    function CanDeleteComponent(AComponent: TComponent): Boolean;
    procedure ExecuteLevelViewsMenuItem(ALevel: TcxGridLevel; AMenuItem: TMenuItem);
    procedure FillLevelViewsMenu(AMenu: TMenuItem; ALevel: TcxGridLevel; AOnClick: TNotifyEvent);
    procedure StructureControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure UpdateDesigner;
  public
    constructor Create(AStructureControl: TcxGridStructureControl); virtual;
    destructor Destroy; override;
    property StructureControl: TcxGridStructureControl read FStructureControl;
    property OnUpdateDesigner: TNotifyEvent read FOnUpdateDesigner write FOnUpdateDesigner;
  end;

  { TcxGridStructureNavigator }

  TcxGridStructureNavigator = class(TcxCustomGridStructureNavigator)
  private
    FCloseButton: TSpeedButton;
    FCustomizeButton: TSpeedButton;
    FDefaultLevel: TcxGridLevel;
    FDefaultView: TcxCustomGridView;
    FDesignHelper: TcxDesignHelper;
    FMakeSelectionVisible: Boolean;
    FSeparator: TBevel;
    FStructureControl: TcxGridStructureControl;
    FStructureHelper: TcxGridStructureHelper;
    procedure CloseButtonClick(Sender: TObject);
    procedure CustomizeButtonClick(Sender: TObject);
    procedure UpdateDesigner(Sender: TObject);
    procedure CMDeferUpdate(var Message: TMessage); message CM_DeferUpdate;
  protected
    procedure Paint; override;
    procedure Calculate;
    function CalculateBoundsRect: TRect; override;
    procedure Changed; override;
    procedure CreateDefaultComponents;
    procedure DrawBackground(ACanvas: TcxCanvas); virtual;
    procedure DrawStructureControlBackground(Sender: TObject);
    function GetClientBounds: TRect; override;
    function GetDefaultViewClass: TcxCustomGridViewClass; virtual;
    function GetDesigner: IDesigner;
    procedure NotifyEditors;
    procedure SelectComponent(AObject: TPersistent; AClearSelection: Boolean);
    property MakeSelectionVisible: Boolean read FMakeSelectionVisible write FMakeSelectionVisible;
  public
    constructor Create(AGrid: TcxCustomGrid); override;
    destructor Destroy; override;
    procedure BeforeGridLoading; override;
    function IsObjectSelected(AObject: TPersistent): Boolean; override;
    procedure SelectionChanged(ASelection: TList); override;
    procedure SelectObject(AObject: TPersistent; AClearSelection: Boolean); override;
    procedure SelectObjects(AObjects: TList); override;
    procedure UnselectObject(AObject: TPersistent); override;
  end;

function GenLevelName(AGrid: TcxCustomGrid; ALevel: TcxGridLevel): string;
function GenViewName(AOwnerComponent: TComponent; AView: TcxCustomGridView): string;
procedure FillRegisteredViewsMenu(AMenu: TMenuItem; AOnClick: TNotifyEvent);

implementation

uses
  Math, dxOffice11, cxLookAndFeelPainters, cxCustomData, cxGridDBTableView,
  cxGridEditor, cxLibraryConsts;

const
  ButtonBorderSize = 1;
  ButtonOffset = 2;
  CloseButtonHeight = 13;
  CloseButtonWidth = 14;
  FrameBorderSize = 1;
  LevelIndent = 16;
  RowBorderWidth = 1;
  RowOffset = 2;
  TextOffset = 2;
  NavigatorOffset = 12;
  // strings
  SCustomizeText = 'Customize...'; // TODO res
  SSubStr = 'TcxGrid';

  cxGridDesignLevelColor = 15851215{16248036};
  cxGridDesignLevelHotColor = 13747387;
  cxGridDesignLevelBorderColor = 13547166;
  cxGridDesignLevelHotBorderColor = 12033927;
  cxGridDesignGridColor = 12639424;
  cxGridDesignGridHotColor = 10800292;
  cxGridDesignGridBorderColor = 10526880;
  cxGridDesignGridHotBorderColor = clDkGray;

type
  TcxCustomGridAccess = class(TcxCustomGrid);

function GenLevelName(AGrid: TcxCustomGrid; ALevel: TcxGridLevel): string;
begin
  Result := CreateUniqueName(AGrid.Owner, AGrid, ALevel, ScxGridPrefixName, '');
end;

function GenViewName(AOwnerComponent: TComponent; AView: TcxCustomGridView): string;
begin
  Result := CreateUniqueName(AOwnerComponent.Owner, AOwnerComponent, AView, ScxGridPrefixName, '');
end;

procedure FillRegisteredViewsMenu(AMenu: TMenuItem; AOnClick: TNotifyEvent);
var
  I: Integer;
begin
  for I := 0 to cxGridRegisteredViews.Count - 1 do
  begin
    if (I <> 0) and (Pos('DB', cxGridRegisteredViews.Descriptions[I]) = 1) and
      (Pos('DB', cxGridRegisteredViews.Descriptions[I - 1]) <> 1) then
      AMenu.Add(CreateMenuItem(AMenu.Owner, '-'));
    AMenu.Add(CreateMenuItem(AMenu.Owner, cxGridRegisteredViews.Descriptions[I],
      AOnClick, True, I));
  end;
end;

procedure CreateCloseBitmap(ABitmap: TBitmap);
var
  ACanvas: TcxCanvas;
  R: TRect;
begin
  R := Rect(0, 0, CloseButtonWidth, CloseButtonHeight);
  with ABitmap do
  begin
    Width := R.Right - R.Left;
    Height := R.Bottom - R.Top;
    Canvas.Brush.Color := clBtnFace;
    Canvas.FillRect(R);
    ACanvas := TcxCanvas.Create(Canvas);
    try
      TcxUltraFlatLookAndFeelPainter.DrawButtonCross(ACanvas, R, clBtnText, cxbsNormal);
    finally
      ACanvas.Free;
    end;
  end;
end;

{$IFDEF DELPHI6}

{ TDesignNotificationHandler }

type
  TDesignNotificationHandler = class(TInterfacedPersistent, IDesignNotification)
  private
    FGrids: TList;
  protected
    // IDesignNotification
    procedure ItemDeleted(const ADesigner: IDesigner; AItem: TPersistent);
    procedure ItemInserted(const ADesigner: IDesigner; AItem: TPersistent);
    procedure ItemsModified(const ADesigner: IDesigner);
    procedure SelectionChanged(const ADesigner: IDesigner; const ASelection: IDesignerSelections);
    procedure DesignerOpened(const ADesigner: IDesigner; AResurrecting: Boolean);
    procedure DesignerClosed(const ADesigner: IDesigner; AGoingDormant: Boolean);
  public
    constructor Create; virtual;
    destructor Destroy; override;
    procedure RegisterGrid(AGrid: TcxCustomGrid);
    procedure UnregisterGrid(AGrid: TcxCustomGrid);
  end;

var
  DesignNotificationHandler: TDesignNotificationHandler;

constructor TDesignNotificationHandler.Create;
begin
  inherited;
  FGrids := TList.Create;
  RegisterDesignNotification(Self);
end;

destructor TDesignNotificationHandler.Destroy;
begin
  UnregisterDesignNotification(Self);
  FGrids.Free;
  inherited;
end;

procedure TDesignNotificationHandler.ItemDeleted(const ADesigner: IDesigner;
  AItem: TPersistent);
begin
end;

procedure TDesignNotificationHandler.ItemInserted(const ADesigner: IDesigner;
  AItem: TPersistent);
begin
end;

procedure TDesignNotificationHandler.ItemsModified(const ADesigner: IDesigner);
begin
end;

procedure TDesignNotificationHandler.SelectionChanged(const ADesigner: IDesigner;
  const ASelection: IDesignerSelections);
var
  ASelectionList: TList;
  I: Integer;
begin
  ASelectionList := TList.Create;
  try
    ConvertSelectionToList(ASelection, ASelectionList);
    for I := 0 to FGrids.Count - 1 do
      TcxCustomGrid(FGrids[I]).StructureNavigator.SelectionChanged(ASelectionList);
  finally
    ASelectionList.Free;
  end;
end;

procedure TDesignNotificationHandler.DesignerOpened(const ADesigner: IDesigner;
  AResurrecting: Boolean);
begin
end;

procedure TDesignNotificationHandler.DesignerClosed(const ADesigner: IDesigner;
  AGoingDormant: Boolean);
begin
end;

procedure TDesignNotificationHandler.RegisterGrid(AGrid: TcxCustomGrid);
begin
  FGrids.Add(AGrid);
end;

procedure TDesignNotificationHandler.UnregisterGrid(AGrid: TcxCustomGrid);
begin
  FGrids.Remove(AGrid);
end;

{$ENDIF}

{ TcxGridStructureControlRowsViewInfo }

function TcxGridStructureControlRowsViewInfo.GetItem(Index: Integer): TcxGridStructureControlRowViewInfo;
begin
  Result := TcxGridStructureControlRowViewInfo(inherited Items[Index]);
end;

{ TcxGridStructureControlViewInfo }

constructor TcxGridStructureControlViewInfo.Create(AStructureControl: TcxGridStructureControl);
begin

⌨️ 快捷键说明

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