Componentes.Terceros.DevExp.../official/x.36/ExpressQuantumGrid 6/Sources/cxGridStdPopupMenu.pas
2008-06-02 17:37:37 +00:00

386 lines
12 KiB
ObjectPascal

{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressQuantumGrid Utils }
{ }
{ 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 cxGridStdPopupMenu;
{$I cxVer.inc}
interface
uses
Windows, Classes, Graphics, ImgList, Menus, cxGridMenuOperations, cxGridCustomPopupMenu,
cxGridCustomView;
type
TcxGridPopupMenuItem = class(TMenuItem)
private
FOperation: TcxGridPopupMenuOperation;
public
constructor Create(AOwner: TComponent; AOperation: TcxGridPopupMenuOperation); reintroduce; virtual;
property Operation: TcxGridPopupMenuOperation read FOperation;
end;
TcxGridStdPopupMenu = class(TPopupMenu, {$IFNDEF DELPHI6}IUnknown,{$ENDIF} IDoPopup, IcxGridPopupMenu)
private
FOperations: TcxGridPopupMenuOperations;
protected
// IDoPopup
function GetPopupHandler: TcxGridOnPopupProc;
// IcxGridPopupMenu
function CanPopup(AHitTest: TcxCustomGridHitTest): Boolean;
{$IFDEF DELPHI7}
procedure AdvancedDrawItem(Sender: TObject; ACanvas: TCanvas;
ARect: TRect; State: TOwnerDrawState); virtual;
{$ENDIF}
procedure CreateMenuItems; virtual;
procedure DoPopup(Sender: TObject); override;
procedure GridMenuPopup(ASenderMenu: TComponent; AHitTest: TcxCustomGridHitTest;
X,Y: Integer); virtual;
function HasDynamicContent: Boolean; virtual;
procedure InitItems(AItems: TMenuItem);
function GetOperationsClass: TcxGridPopupMenuOperationsClass; virtual; abstract;
property Operations: TcxGridPopupMenuOperations read FOperations;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
TcxGridStdHeaderMenu = class(TcxGridStdPopupMenu)
protected
function GetOperationsClass: TcxGridPopupMenuOperationsClass; override;
end;
TcxGridStdFooterMenu = class(TcxGridStdPopupMenu)
protected
function GetOperationsClass: TcxGridPopupMenuOperationsClass; override;
end;
TcxGridStdGroupRowMenu = class(TcxGridStdPopupMenu)
protected
function GetOperationsClass: TcxGridPopupMenuOperationsClass; override;
procedure GridMenuPopup(ASenderMenu: TComponent; AHitTest: TcxCustomGridHitTest;
X,Y: Integer); override;
function HasDynamicContent: Boolean; override;
end;
function cxGetGridPopupMenuOperation(AMenuItem: TComponent): TcxGridPopupMenuOperation;
implementation
uses
Types,
{$IFDEF DELPHI7}
Themes,
{$ENDIF}
SysUtils, cxGraphics, cxGeometry, cxLookAndFeelPainters, cxGridCustomTableView, cxGridTableView,
cxGridHeaderPopupMenuItems, cxGridFooterPopupMenuItems, cxGridGroupRowPopupMenuItems;
function cxGetGridPopupMenuOperation(AMenuItem: TComponent): TcxGridPopupMenuOperation;
begin
if AMenuItem is TcxGridPopupMenuItem then
Result := TcxGridPopupMenuItem(AMenuItem).Operation
else
Result := nil;
end;
{ TcxGridPopupMenuItem }
constructor TcxGridPopupMenuItem.Create(AOwner: TComponent; AOperation: TcxGridPopupMenuOperation);
begin
inherited Create(AOwner);
FOperation := AOperation;
end;
{ TcxGridStdPopupMenu }
constructor TcxGridStdPopupMenu.Create(AOwner: TComponent);
begin
inherited;
FOperations := GetOperationsClass.Create;
if not HasDynamicContent then
CreateMenuItems;
end;
destructor TcxGridStdPopupMenu.Destroy;
begin
FOperations.Free;
inherited;
end;
function TcxGridStdPopupMenu.GetPopupHandler: TcxGridOnPopupProc;
begin
Result := GridMenuPopup;
end;
function TcxGridStdPopupMenu.CanPopup(AHitTest: TcxCustomGridHitTest): Boolean;
begin
Result := Operations.CanProcess(AHitTest);
end;
{$IFDEF DELPHI7}
procedure TcxGridStdPopupMenu.AdvancedDrawItem(Sender: TObject;
ACanvas: TCanvas; ARect: TRect; State: TOwnerDrawState);
var
AMenuItem: TcxGridPopupMenuItem;
AImages: TCustomImageList;
ASelected, AHasImage: Boolean;
AImageAreaRect, AImageRect, ACheckRect: TRect;
AcxCanvas: TcxCanvas;
begin
AMenuItem := TcxGridPopupMenuItem(Sender);
AImages := AMenuItem.GetParentMenu.Images;
ASelected := odSelected in State;
AHasImage := (0 <= AMenuItem.ImageIndex) and (AMenuItem.ImageIndex < AImages.Count);
// draw background
if ASelected then
begin
if ThemeServices.ThemesEnabled then
ACanvas.Brush.Color := clMenuHighlight
else
ACanvas.Brush.Color := clHighlight;
ACanvas.Font.Color := clHighlightText;
end;
ACanvas.FillRect(ARect);
// draw image
AImageAreaRect := ARect;
AImageAreaRect.Right := AImageAreaRect.Left + cxRectHeight(AImageAreaRect);
AImageRect := Bounds(AImageAreaRect.Left + 1, AImageAreaRect.Top + 1,
AImages.Width, AImages.Height);
if AMenuItem.Checked then
begin
ACanvas.Brush.Color := clBtnShadow;
ACanvas.FrameRect(AImageAreaRect);
InflateRect(AImageAreaRect, -1, -1);
ACanvas.Brush.Color := clBtnFace;
ACanvas.FillRect(AImageAreaRect);
InflateRect(AImageAreaRect, 1, 1);
if not AHasImage then
begin
ACheckRect := cxRectCenter(AImageAreaRect, TcxCustomLookAndFeelPainter.CheckButtonSize);
InflateRect(ACheckRect, -TcxCustomLookAndFeelPainter.CheckBorderSize,
-TcxCustomLookAndFeelPainter.CheckBorderSize);
AcxCanvas := TcxCanvas.Create(ACanvas);
try
AcxCanvas.Brush.Style := bsClear;
TcxCustomLookAndFeelPainter.DrawCheck(AcxCanvas, ACheckRect, cxbsNormal,
True, clBtnText);
AcxCanvas.Brush.Style := bsSolid;
finally
AcxCanvas.Free;
end;
end;
end;
if AHasImage then
AImages.Draw(ACanvas, AImageRect.Left, AImageRect.Top, AMenuItem.ImageIndex,
AMenuItem.Enabled);
// draw text
ARect.Left := AImageAreaRect.Right + 3;
Dec(ARect.Right);
AMenuItem.DoDrawText(ACanvas, AMenuItem.Caption, ARect, ASelected,
DT_SINGLELINE or DT_EXPANDTABS or DT_LEFT or DT_VCENTER);
if AMenuItem.ShortCut <> 0 then
begin
Dec(ARect.Right, 10);
AMenuItem.DoDrawText(ACanvas, ShortCutToText(AMenuItem.ShortCut), ARect,
ASelected, DT_SINGLELINE or DT_RIGHT or DT_VCENTER);
end;
end;
{$ENDIF}
procedure TcxGridStdPopupMenu.CreateMenuItems;
procedure InsertNewGroup(AItems: TMenuItem);
var
AItem: TcxGridPopupMenuItem;
begin
AItem := TcxGridPopupMenuItem.Create(Self, nil);
AItem.Caption := '-';
AItems.Add(AItem);
end;
function GetMenuItemByOperationClass(const AItems: TMenuItem;
AClass: TcxGridPopupMenuOperationClass): TMenuItem;
var
I: Integer;
AOperation: TcxGridPopupMenuOperation;
begin
for I := 0 to AItems.Count - 1 do
begin
Result := AItems[I];
AOperation := cxGetGridPopupMenuOperation(Result);
if (AOperation <> nil) and (AOperation.ClassType = AClass) then
Exit
else
begin
Result := GetMenuItemByOperationClass(Result, AClass);
if Result <> nil then Exit;
end;
end;
Result := nil;
end;
var
I: Integer;
AOperation: TcxGridPopupMenuOperation;
AMenuItem, AParentMenuItem: TMenuItem;
begin
for I := 0 to Operations.Count - 1 do
begin
AOperation := Operations[I];
AMenuItem := TcxGridPopupMenuItem.Create(Self, AOperation);
if AOperation.GetParentOperationClass = nil then
AParentMenuItem := nil
else
AParentMenuItem := GetMenuItemByOperationClass(Items, AOperation.GetParentOperationClass);
if AParentMenuItem = nil then
AParentMenuItem := Items;
if AOperation.BeginGroup then
InsertNewGroup(AParentMenuItem);
AParentMenuItem.Add(AMenuItem);
end;
end;
procedure TcxGridStdPopupMenu.DoPopup(Sender: TObject);
begin
if HasDynamicContent then
begin
Items.Clear;
CreateMenuItems;
end;
Images := cxGridPopupMenuImages;
InitItems(Items);
inherited DoPopup(Sender);
end;
procedure TcxGridStdPopupMenu.GridMenuPopup(ASenderMenu: TComponent;
AHitTest: TcxCustomGridHitTest; X, Y: Integer);
begin
Popup(X, Y);
end;
function TcxGridStdPopupMenu.HasDynamicContent: Boolean;
begin
Result := False;
end;
procedure TcxGridStdPopupMenu.InitItems(AItems: TMenuItem);
var
{$IFDEF DELPHI7}
ACustomDrawNeeded: Boolean;
{$ENDIF}
I: Integer;
AOperation: TcxGridPopupMenuOperation;
begin
{$IFDEF DELPHI7}
ACustomDrawNeeded := (Win32MajorVersion >= 5) and (Win32MinorVersion >= 1) and
(Images <> nil) and not IsRightToLeft;
{$ENDIF}
for I := 0 to AItems.Count - 1 do
begin
AOperation := cxGetGridPopupMenuOperation(AItems[I]);
if AOperation <> nil then
begin
AItems[I].Caption := AOperation.Caption;
AItems[I].Checked := AOperation.Down;
AItems[I].Enabled := AOperation.Enabled;
AItems[I].ImageIndex := AOperation.ImageIndex;
AItems[I].Visible := AOperation.Visible;
AItems[I].OnClick := AOperation.DoExecute;
{$IFDEF DELPHI7}
if ACustomDrawNeeded then
AItems[I].OnAdvancedDrawItem := AdvancedDrawItem;
{$ENDIF}
end;
InitItems(AItems[I]);
end;
end;
{ TcxGridStdHeaderMenu }
function TcxGridStdHeaderMenu.GetOperationsClass: TcxGridPopupMenuOperationsClass;
begin
Result := TcxGridHeaderPopupMenuOperations;
end;
{ TcxGridStdFooterMenu }
function TcxGridStdFooterMenu.GetOperationsClass: TcxGridPopupMenuOperationsClass;
begin
Result := TcxGridFooterPopupMenuOperations;
end;
{ TcxGridStdGroupRowMenu }
function TcxGridStdGroupRowMenu.GetOperationsClass: TcxGridPopupMenuOperationsClass;
begin
Result := TcxGridGroupRowPopupMenuOperations;
end;
procedure TcxGridStdGroupRowMenu.GridMenuPopup(ASenderMenu: TComponent;
AHitTest: TcxCustomGridHitTest; X, Y: Integer);
begin
TcxGridGroupRowPopupMenuOperations(Operations).GroupRow :=
(AHitTest as TcxGridRecordHitTest).GridRecord as TcxGridGroupRow;
inherited;
end;
function TcxGridStdGroupRowMenu.HasDynamicContent: Boolean;
begin
Result := True;
end;
initialization
RegisterPopupMenuClass(TcxGridStdHeaderMenu, [gvhtColumnHeader], TcxGridTableView);
RegisterPopupMenuClass(TcxGridStdFooterMenu, [gvhtFooterCell, gvhtGroupFooterCell],
TcxGridTableView);
RegisterPopupMenuClass(TcxGridStdGroupRowMenu, [gvhtRecord, gvhtGroupSummary],
TcxGridTableView);
finalization
UnregisterPopupMenuClass(TcxGridStdGroupRowMenu);
UnregisterPopupMenuClass(TcxGridStdFooterMenu);
UnregisterPopupMenuClass(TcxGridStdHeaderMenu);
end.