Componentes.Terceros.DevExp.../internal/x.46/2/ExpressEditors Library 5/Sources/cxNavigator.pas

1876 lines
58 KiB
ObjectPascal

{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressEditors }
{ }
{ Copyright (c) 1998-2009 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 EXPRESSEDITORS 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 cxNavigator;
{$I cxVer.inc}
interface
uses
{$IFDEF DELPHI6}
Types,
{$ENDIF}
Messages, Windows, Classes, Controls, Forms, Graphics, ImgList,
StdCtrls, SysUtils, cxClasses, cxContainer, cxControls, cxFilter, cxGraphics,
cxLookAndFeels, cxLookAndFeelPainters, dxThemeManager;
const
NavigatorButtonCount = 16;
NBDI_FIRST = 0;
NBDI_PRIORPAGE = 1;
NBDI_PRIOR = 2;
NBDI_NEXT = 3;
NBDI_NEXTPAGE = 4;
NBDI_LAST = 5;
NBDI_INSERT = 6;
NBDI_APPEND = 7;
NBDI_DELETE = 8;
NBDI_EDIT = 9;
NBDI_POST = 10;
NBDI_CANCEL = 11;
NBDI_REFRESH = 12;
NBDI_SAVEBOOKMARK = 13;
NBDI_GOTOBOOKMARK = 14;
NBDI_FILTER = 15;
type
TcxCustomNavigatorButtons = class;
TcxNavigatorChangeType = (nctProperties, nctSize, nctLayout);
IcxNavigatorOwner = interface
['{504B7F43-8847-46C5-B84A-C24F8E5E61A6}']
procedure NavigatorChanged(AChangeType: TcxNavigatorChangeType);
function GetNavigatorBounds: TRect;
function GetNavigatorButtons: TcxCustomNavigatorButtons;
function GetNavigatorCanvas: TCanvas;
function GetNavigatorControl: TWinControl;
function GetNavigatorFocused: Boolean;
function GetNavigatorLookAndFeel: TcxLookAndFeel;
function GetNavigatorOwner: TComponent;
function GetNavigatorShowHint: Boolean;
function GetNavigatorTabStop: Boolean;
procedure NavigatorButtonsStateChanged;
procedure RefreshNavigator;
end;
TcxNavigatorButton = class(TPersistent)
private
FButtons: TcxCustomNavigatorButtons;
FDefaultIndex: Integer;
FDefaultVisible: Boolean;
FEnabled: Boolean;
FHint: string;
FImageIndex: TImageIndex;
FIsVisibleAssigned: Boolean;
FVisible: Boolean;
FOnClick: TNotifyEvent;
function GetInternalImageIndex: Integer;
function GetIternalImages: TCustomImageList;
procedure InternalSetVisible(Value: Boolean; AIsInternalSetting: Boolean = True);
function IsVisibleStored: Boolean;
procedure SetEnabled(const Value: Boolean);
procedure SetHint(const Value: string);
procedure SetImageIndex(Value: TImageIndex);
procedure SetOnClick(const Value: TNotifyEvent);
procedure SetVisible(const Value: Boolean);
protected
function GetOwner: TPersistent; override;
function GetInternalEnabled: Boolean;
function GetInternalHint: string;
function IsUserImageListUsed: Boolean;
procedure DoClick; dynamic;
procedure RestoreDefaultVisible(ACanBeVisible: Boolean);
function GetNavigator: IcxNavigatorOwner;
property DefaultIndex: Integer read FDefaultIndex write FDefaultIndex;
property InternalImageIndex: Integer read GetInternalImageIndex;
property InternalImages: TCustomImageList read GetIternalImages;
public
constructor Create(AButtons: TcxCustomNavigatorButtons;
ADefaultVisible: Boolean);
procedure Assign(Source: TPersistent); override;
procedure Click;
function GetImageSize: TSize;
property Buttons: TcxCustomNavigatorButtons read FButtons;
property Navigator: IcxNavigatorOwner read GetNavigator;
property OnClick: TNotifyEvent read FOnClick write SetOnClick;
published
property Enabled: Boolean read FEnabled write SetEnabled default True;
property Hint: string read FHint write SetHint;
property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1;
property Visible: Boolean read FVisible write SetVisible stored IsVisibleStored;
end;
TcxCustomNavigator = class;
TcxNavigatorButtonClickEvent = procedure(Sender: TObject; AButtonIndex: Integer;
var ADone: Boolean) of object;
TcxCustomNavigatorButtons = class(TPersistent)
private
FNavigator: IcxNavigatorOwner;
FButtons: array [0 .. NavigatorButtonCount - 1] of TcxNavigatorButton;
FImages: TCustomImageList;
FImageChangeLink: TChangeLink;
FConfirmDelete: Boolean;
FOnButtonClick: TcxNavigatorButtonClickEvent;
function GetButton(Index: Integer): TcxNavigatorButton;
function GetButtonCount: Integer;
function GetDefaultImages: TCustomImageList;
procedure SetButton(Index: Integer; const Value: TcxNavigatorButton);
procedure SetConfirmDelete(const Value: Boolean);
procedure SetImages(const Value: TCustomImageList);
procedure SetOnButtonClick(const Value: TcxNavigatorButtonClickEvent);
procedure ImageListChange(Sender: TObject);
protected
function GetOwner: TPersistent; override;
procedure CreateButtons; virtual;
procedure DestroyButtons; virtual;
procedure DoButtonClick(ADefaultIndex: Integer); virtual;
function GetButtonEnabled(ADefaultIndex: Integer): Boolean; virtual;
function GetButtonHint(ADefaultIndex: Integer): string; virtual;
function GetButtonImageOffset: Integer; virtual;
function IsNavigatorEnabled: Boolean;
property ConfirmDelete: Boolean read FConfirmDelete write SetConfirmDelete default True;
property First: TcxNavigatorButton index NBDI_FIRST read GetButton write SetButton;
property PriorPage: TcxNavigatorButton index NBDI_PRIORPAGE read GetButton write SetButton;
property Prior: TcxNavigatorButton index NBDI_PRIOR read GetButton write SetButton;
property Next: TcxNavigatorButton index NBDI_NEXT read GetButton write SetButton;
property NextPage: TcxNavigatorButton index NBDI_NEXTPAGE read GetButton write SetButton;
property Last: TcxNavigatorButton index NBDI_LAST read GetButton write SetButton;
property Insert: TcxNavigatorButton index NBDI_INSERT read GetButton write SetButton;
property Append: TcxNavigatorButton index NBDI_APPEND read GetButton write SetButton;
property Delete: TcxNavigatorButton index NBDI_DELETE read GetButton write SetButton;
property Edit: TcxNavigatorButton index NBDI_EDIT read GetButton write SetButton;
property Post: TcxNavigatorButton index NBDI_POST read GetButton write SetButton;
property Cancel: TcxNavigatorButton index NBDI_CANCEL read GetButton write SetButton;
property Refresh: TcxNavigatorButton index NBDI_REFRESH read GetButton write SetButton;
property SaveBookmark: TcxNavigatorButton index NBDI_SAVEBOOKMARK read GetButton write SetButton;
property GotoBookmark: TcxNavigatorButton index NBDI_GOTOBOOKMARK read GetButton write SetButton;
property Filter: TcxNavigatorButton index NBDI_FILTER read GetButton write SetButton;
public
constructor Create(ANavigator: IcxNavigatorOwner); virtual;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure ClickButton(Index: Integer);
procedure ReleaseBookmark; virtual;
property ButtonCount: Integer read GetButtonCount;
property Buttons[Index: Integer]: TcxNavigatorButton read GetButton; default;
property DefaultImages: TCustomImageList read GetDefaultImages;
property Images: TCustomImageList read FImages write SetImages;
property Navigator: IcxNavigatorOwner read FNavigator;
published
property OnButtonClick: TcxNavigatorButtonClickEvent read FOnButtonClick
write SetOnButtonClick;
end;
TcxNavigatorButtonViewInfo = class
public
Button: TcxNavigatorButton;
Bounds: TRect;
Enabled: Boolean;
Hint: string;
end;
TcxNavigatorViewInfo = class
private
FButtonPressTimer: TcxTimer;
FButtons: TList;
FCanvas: TcxCanvas;
FFocusedButton: TcxNavigatorButton;
FHintTimer: TcxTimer;
FHintWindow: THintWindow;
FHintWindowShowing: Boolean;
FHotTrackButtonViewInfo: TcxNavigatorButtonViewInfo;
FIsDirty: Boolean;
FIsInplace: Boolean;
FIsSelected: Boolean;
FNavigator: IcxNavigatorOwner;
FPressedButtonViewInfo: TcxNavigatorButtonViewInfo;
function GetButton(Index: Integer): TcxNavigatorButtonViewInfo;
function GetButtonCount: Integer;
function GetFocusedButton: TcxNavigatorButtonViewInfo;
procedure SetFocusedButton(Value: TcxNavigatorButtonViewInfo);
function StopButtonPressTimerIfLeftMouseReleased: Boolean;
procedure DoButtonPressTimer(Sender: TObject);
procedure DoHintTimer(Sender: TObject);
procedure UpdateSelected;
protected
function GetButtonBorderExtent(APainter: TcxCustomLookAndFeelPainterClass;
AButtonIndex, AButtonCount: Integer): TRect;
function GetButtonState(AButton: TcxNavigatorButtonViewInfo): TcxButtonState;
function GetMiddleButtonBorderExtent(APainter: TcxCustomLookAndFeelPainterClass): TRect;
function GetMinButtonSize(AButtonIndex, AButtonCount: Integer;
AAutoHeight: Boolean = False): TSize;
function GetVisibleButtonCount: Integer;
procedure InvalidateButton(AButton: TcxNavigatorButtonViewInfo);
procedure PaintButton(AButtonIndex: Integer);
procedure HintActivate(AShow: Boolean);
property Canvas: TcxCanvas read FCanvas;
property FocusedButton: TcxNavigatorButtonViewInfo read GetFocusedButton
write SetFocusedButton;
property HotTrackButtonViewInfo: TcxNavigatorButtonViewInfo
read FHotTrackButtonViewInfo write FHotTrackButtonViewInfo;
property Navigator: IcxNavigatorOwner read FNavigator;
property PressedButtonViewInfo: TcxNavigatorButtonViewInfo
read FPressedButtonViewInfo write FPressedButtonViewInfo;
public
constructor Create(ANavigator: IcxNavigatorOwner;
AIsInplace: Boolean = True); virtual;
destructor Destroy; override;
procedure Calculate;
procedure CheckSize(var AWidth, AHeight: Integer;
ACheckMinHeight: Boolean = False);
procedure Clear;
procedure DoEnter;
procedure DoExit;
function GetButtonAt(const pt: TPoint): TcxNavigatorButton;
function GetButtonViewInfoAt(const pt: TPoint): TcxNavigatorButtonViewInfo;
function GetButtonViewInfoByButton(AButton: TcxNavigatorButton): TcxNavigatorButtonViewInfo;
procedure MakeIsDirty;
procedure MouseDown(X, Y: Integer);
procedure MouseMove(X, Y: Integer);
procedure MouseUp(X, Y: Integer);
procedure Paint;
procedure PressArrowKey(ALeftKey: Boolean);
procedure UpdateButtonsEnabled;
property ButtonCount: Integer read GetButtonCount;
property Buttons[Index: Integer]: TcxNavigatorButtonViewInfo read GetButton;
end;
TcxNavigatorViewInfoClass = class of TcxNavigatorViewInfo;
TcxCustomNavigator = class(TcxControl, IUnknown,
IcxNavigatorOwner, IcxMouseTrackingCaller, IdxSkinSupport)
private
FButtons: TcxCustomNavigatorButtons;
FButtonsEvents: TNotifyEvent;
FViewInfo: TcxNavigatorViewInfo;
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW;
protected
function CanFocusOnClick: Boolean; override;
function CanResize(var NewWidth, NewHeight: Integer): Boolean; override;
function CreateButtons: TcxCustomNavigatorButtons; virtual;
procedure DoEnter; override;
procedure DoExit; override;
procedure EnabledChanged; dynamic;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure LookAndFeelChanged(Sender: TcxLookAndFeel;
AChangedValues: TcxLookAndFeelValues); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseEnter(AControl: TControl); override;
procedure MouseLeave(AControl: TControl); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure Paint; override;
//IcxMouseTrackingCaller
procedure IcxMouseTrackingCaller.MouseLeave = NavigatorMouseLeave;
procedure NavigatorMouseLeave;
// IcxNavigatorOwner
procedure NavigatorChanged(AChangeType: TcxNavigatorChangeType);
function GetNavigatorBounds: TRect;
function GetNavigatorButtons: TcxCustomNavigatorButtons;
function GetNavigatorCanvas: TCanvas;
function GetNavigatorControl: TWinControl;
function GetNavigatorFocused: Boolean;
function GetNavigatorLookAndFeel: TcxLookAndFeel;
function GetNavigatorOwner: TComponent;
function GetNavigatorShowHint: Boolean;
function GetNavigatorTabStop: Boolean;
function GetViewInfoClass: TcxNavigatorViewInfoClass; virtual;
procedure InitButtons; virtual;
procedure NavigatorButtonsStateChanged;
procedure RefreshNavigator;
procedure CreateWnd; override;
procedure WndProc(var Message: TMessage); override;
property CustomButtons: TcxCustomNavigatorButtons read FButtons;
property ViewInfo: TcxNavigatorViewInfo read FViewInfo;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure ClickButton(Index: Integer);
procedure RestoreButtons;
property LookAndFeel;
published
property TabStop default False;
property ButtonsEvents: TNotifyEvent read FButtonsEvents
write FButtonsEvents;
end;
TcxNavigatorControlNotifier = class
private
FList: TList;
public
constructor Create;
destructor Destroy; override;
procedure AddNavigator(ANavigator: IcxNavigatorOwner);
procedure RemoveNavigator(ANavigator: IcxNavigatorOwner);
procedure RefreshNavigatorButtons;
end;
IcxNavigator = interface
['{A15F80CA-DE56-47CB-B0EB-035D0BF90E9D}']
function CanAppend: Boolean;
function CanDelete: Boolean;
function CanEdit: Boolean;
function CanInsert: Boolean;
function IsActive: Boolean;
function IsBof: Boolean;
function IsBookmarkAvailable: Boolean;
function IsEditing: Boolean;
function IsEof: Boolean;
procedure ClearBookmark;
procedure DoAction(AButtonIndex: Integer);
function GetNotifier: TcxNavigatorControlNotifier;
function IsActionSupported(AButtonIndex: Integer): Boolean;
end;
TcxNavigatorControlButtonsGetControl = function: IcxNavigator of object;
TcxNavigatorControlButtons = class(TcxCustomNavigatorButtons)
private
FOnGetControl: TcxNavigatorControlButtonsGetControl;
function GetControl: IcxNavigator;
protected
procedure DoButtonClick(ADefaultIndex: Integer); override;
function GetButtonEnabled(ADefaultIndex: Integer): Boolean; override;
property Control: IcxNavigator read GetControl;
public
procedure ReleaseBookmark; override;
property OnGetControl: TcxNavigatorControlButtonsGetControl
read FOnGetControl write FOnGetControl;
published
property ConfirmDelete;
property Images;
property First;
property PriorPage;
property Prior;
property Next;
property NextPage;
property Last;
property Insert;
property Append;
property Delete;
property Edit;
property Post;
property Cancel;
property Refresh;
property SaveBookmark;
property GotoBookmark;
property Filter;
end;
TcxNavigatorControlButtonsClass = class of TcxNavigatorControlButtons;
TcxCustomNavigatorControl = class(TcxCustomNavigator)
private
FControl: TComponent;
function GetButtons: TcxNavigatorControlButtons;
function GetControl: IcxNavigator;
procedure SetButtons(Value: TcxNavigatorControlButtons);
procedure SetControl(Value: TComponent);
protected
function CreateButtons: TcxCustomNavigatorButtons; override;
function GetButtonsClass: TcxNavigatorControlButtonsClass; virtual;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure InitButtons; override;
property Buttons: TcxNavigatorControlButtons read GetButtons write SetButtons;
property Control: TComponent read FControl write SetControl;
public
destructor Destroy; override;
end;
TcxNavigator = class(TcxCustomNavigatorControl)
published
property Control;
property Buttons;
property LookAndFeel;
property Align;
property Anchors;
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Ctl3D;
property ParentCtl3D;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
{$IFDEF DELPHI5}
property OnContextPopup;
{$ENDIF}
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnResize;
property OnStartDock;
property OnStartDrag;
end;
function NavigatorImages: TImageList;
implementation
uses
Dialogs, cxEditPaintUtils, cxEditUtils, cxEditConsts, dxThemeConsts, dxUxTheme,
cxGeometry;
const
cxInitRepeatPause = 400;
cxRepeatPause = 100;
type
TCustomFormAccess = class(TCustomForm);
var
FNavigatorImages: TImageList = nil;
function NavigatorImages: TImageList;
procedure LoadImageListFromResource(AImageList: TCustomImageList;
const AResName: string; AMaskColor: TColor);
begin
AImageList.GetInstRes(HInstance, rtBitmap, AResName,
AImageList.Width, [], AMaskColor);
end;
begin
if FNavigatorImages = nil then
begin
FNavigatorImages := TImageList.Create(nil);
FNavigatorImages.Height := 11;
FNavigatorImages.Width := 12;
LoadImageListFromResource(FNavigatorImages, 'CXNAVIGATORBUTTONS', clOlive);
end;
Result := FNavigatorImages;
end;
{ TcxNavigatorButton }
constructor TcxNavigatorButton.Create(AButtons: TcxCustomNavigatorButtons;
ADefaultVisible: Boolean);
begin
inherited Create;
FButtons := AButtons;
FDefaultIndex := -1;
FDefaultVisible := ADefaultVisible;
FEnabled := True;
FImageIndex := -1;
FVisible := ADefaultVisible;
end;
function TcxNavigatorButton.GetOwner: TPersistent;
begin
Result := FButtons;
end;
procedure TcxNavigatorButton.Assign(Source: TPersistent);
begin
if Source is TcxNavigatorButton then
with Source as TcxNavigatorButton do
begin
Self.Enabled := Enabled;
Self.Hint := Hint;
Self.ImageIndex := ImageIndex;
Self.Visible := Visible;
Self.FIsVisibleAssigned := FIsVisibleAssigned;
Self.OnClick := OnClick;
end
else
inherited Assign(Source);
end;
procedure TcxNavigatorButton.Click;
begin
if GetInternalEnabled then
DoClick;
end;
function TcxNavigatorButton.GetInternalEnabled: Boolean;
begin
Result := Enabled;
if Result then
Result := Buttons.GetButtonEnabled(DefaultIndex);
end;
function TcxNavigatorButton.GetInternalHint: string;
begin
Result := Hint;
if Hint = '' then
Result := Buttons.GetButtonHint(DefaultIndex);
end;
function TcxNavigatorButton.IsUserImageListUsed: Boolean;
begin
Result := (Buttons.Images <> nil) and (ImageIndex > -1);
end;
procedure TcxNavigatorButton.DoClick;
var
ADone: Boolean;
begin
if Assigned(OnClick) then
OnClick(Self)
else
begin
ADone := False;
if Assigned(Buttons.FOnButtonClick) then
Buttons.FOnButtonClick(Buttons, DefaultIndex, ADone);
if not ADone then
Buttons.DoButtonClick(DefaultIndex);
end;
end;
procedure TcxNavigatorButton.RestoreDefaultVisible(ACanBeVisible: Boolean);
begin
if not FIsVisibleAssigned then
InternalSetVisible(FDefaultVisible and ACanBeVisible);
end;
function TcxNavigatorButton.GetImageSize: TSize;
var
APainter: TcxCustomLookAndFeelPainterClass;
begin
APainter := GetNavigator.GetNavigatorLookAndFeel.SkinPainter;
if (APainter = nil) or IsUserImageListUsed then
begin
Result.cx := InternalImages.Width;
Result.cy := InternalImages.Height;
end
else
Result := APainter.NavigatorGlyphSize;
end;
function TcxNavigatorButton.GetNavigator: IcxNavigatorOwner;
begin
Result := Buttons.Navigator;
end;
procedure TcxNavigatorButton.SetEnabled(const Value: Boolean);
begin
if Enabled <> Value then
begin
FEnabled := Value;
if Visible then
Navigator.RefreshNavigator;
Navigator.NavigatorChanged(nctLayout);
end;
end;
procedure TcxNavigatorButton.SetHint(const Value: string);
begin
if AnsiCompareStr(FHint, Value) <> 0 then
begin
FHint := Value;
Navigator.NavigatorChanged(nctProperties);
end;
end;
function TcxNavigatorButton.GetInternalImageIndex: Integer;
begin
if (Buttons.Images <> nil) and (ImageIndex > -1) then
Result := ImageIndex
else
Result := DefaultIndex;
end;
function TcxNavigatorButton.GetIternalImages: TCustomImageList;
begin
if (Buttons.Images <> nil) and (ImageIndex > -1) then
Result := Buttons.Images
else
Result := Buttons.DefaultImages;
end;
procedure TcxNavigatorButton.InternalSetVisible(Value: Boolean;
AIsInternalSetting: Boolean = True);
begin
if not AIsInternalSetting then
FIsVisibleAssigned := True;
if FVisible <> Value then
begin
FVisible := Value;
Navigator.RefreshNavigator;
Navigator.NavigatorChanged(nctSize);
end;
end;
function TcxNavigatorButton.IsVisibleStored: Boolean;
begin
Result := FIsVisibleAssigned;
end;
procedure TcxNavigatorButton.SetImageIndex(Value: TImageIndex);
begin
if ImageIndex <> Value then
begin
FImageIndex := Value;
if Visible then
Navigator.RefreshNavigator;
Navigator.NavigatorChanged(nctLayout);
end;
end;
procedure TcxNavigatorButton.SetOnClick(const Value: TNotifyEvent);
begin
FOnClick := Value;
Navigator.NavigatorChanged(nctProperties);
end;
procedure TcxNavigatorButton.SetVisible(const Value: Boolean);
begin
InternalSetVisible(Value, False);
end;
{ TcxCustomNavigatorButtons }
constructor TcxCustomNavigatorButtons.Create(ANavigator: IcxNavigatorOwner);
begin
inherited Create;
FNavigator := ANavigator;
FImageChangeLink := TChangeLink.Create;
FImageChangeLink.OnChange := ImageListChange;
CreateButtons;
FConfirmDelete := True;
end;
destructor TcxCustomNavigatorButtons.Destroy;
begin
FreeAndNil(FImageChangeLink);
DestroyButtons;
inherited Destroy;
end;
procedure TcxCustomNavigatorButtons.Assign(Source: TPersistent);
var
I: Integer;
begin
if Source is TcxCustomNavigatorButtons then
with TcxCustomNavigatorButtons(Source) do
begin
for I := 0 to ButtonCount - 1 do
Self.FButtons[I].Assign(FButtons[I]);
Self.ConfirmDelete := ConfirmDelete;
Self.Images := Images;
Self.OnButtonClick := OnButtonClick;
end
else
inherited Assign(Source);
end;
procedure TcxCustomNavigatorButtons.ClickButton(Index: Integer);
begin
Buttons[Index].Click;
end;
procedure TcxCustomNavigatorButtons.ReleaseBookmark;
begin
end;
procedure TcxCustomNavigatorButtons.CreateButtons;
function IsButtonVisibleByDefault(AIndex: Integer): Boolean;
begin
Result := AIndex <> NBDI_APPEND;
end;
var
I: Integer;
begin
for I := 0 to NavigatorButtonCount - 1 do
begin
FButtons[I] := TcxNavigatorButton.Create(Self, IsButtonVisibleByDefault(I));
FButtons[I].DefaultIndex := I;
end;
end;
function TcxCustomNavigatorButtons.GetOwner: TPersistent;
begin
Result := FNavigator.GetNavigatorOwner;
end;
procedure TcxCustomNavigatorButtons.DestroyButtons;
var
I: Integer;
begin
for I := 0 to NavigatorButtonCount - 1 do
FButtons[I].Free;
end;
procedure TcxCustomNavigatorButtons.DoButtonClick(ADefaultIndex: Integer);
begin
end;
function TcxCustomNavigatorButtons.GetButtonEnabled(ADefaultIndex: Integer): Boolean;
begin
Result := IsNavigatorEnabled;
end;
function TcxCustomNavigatorButtons.GetButtonHint(ADefaultIndex: Integer): string;
begin
case ADefaultIndex of
NBDI_FIRST: Result := cxGetResourceString(@cxNavigatorHint_First);
NBDI_PRIORPAGE: Result := cxGetResourceString(@cxNavigatorHint_PriorPage);
NBDI_PRIOR: Result := cxGetResourceString(@cxNavigatorHint_Prior);
NBDI_LAST: Result := cxGetResourceString(@cxNavigatorHint_Last);
NBDI_NEXT: Result := cxGetResourceString(@cxNavigatorHint_Next);
NBDI_NEXTPAGE: Result := cxGetResourceString(@cxNavigatorHint_NextPage);
NBDI_INSERT: Result := cxGetResourceString(@cxNavigatorHint_Insert);
NBDI_APPEND: Result := cxGetResourceString(@cxNavigatorHint_Append);
NBDI_DELETE: Result := cxGetResourceString(@cxNavigatorHint_Delete);
NBDI_EDIT: Result := cxGetResourceString(@cxNavigatorHint_Edit);
NBDI_POST: Result := cxGetResourceString(@cxNavigatorHint_Post);
NBDI_CANCEL: Result := cxGetResourceString(@cxNavigatorHint_Cancel);
NBDI_REFRESH: Result := cxGetResourceString(@cxNavigatorHint_Refresh);
NBDI_SAVEBOOKMARK: Result := cxGetResourceString(@cxNavigatorHint_SaveBookmark);
NBDI_GOTOBOOKMARK: Result := cxGetResourceString(@cxNavigatorHint_GotoBookmark);
NBDI_FILTER: Result := cxGetResourceString(@cxNavigatorHint_Filter);
else Result := '';
end;
end;
function TcxCustomNavigatorButtons.GetButtonImageOffset: Integer;
begin
Result := 2;
end;
function TcxCustomNavigatorButtons.IsNavigatorEnabled: Boolean;
begin
Result := Navigator.GetNavigatorControl.Enabled;
end;
function TcxCustomNavigatorButtons.GetButton(Index: Integer): TcxNavigatorButton;
begin
Result := FButtons[Index];
end;
function TcxCustomNavigatorButtons.GetButtonCount: Integer;
begin
Result := High(FButtons) - Low(FButtons) + 1;
end;
function TcxCustomNavigatorButtons.GetDefaultImages: TCustomImageList;
begin
Result := NavigatorImages;
end;
procedure TcxCustomNavigatorButtons.SetButton(Index: Integer; const Value: TcxNavigatorButton);
begin
FButtons[Index].Assign(Value);
end;
procedure TcxCustomNavigatorButtons.SetConfirmDelete(const Value: Boolean);
begin
if FConfirmDelete <> Value then
begin
FConfirmDelete := Value;
Navigator.NavigatorChanged(nctProperties);
end;
end;
procedure TcxCustomNavigatorButtons.SetImages(const Value: TCustomImageList);
begin
cxSetImageList(Value, FImages, FImageChangeLink, Navigator.GetNavigatorOwner);
Navigator.NavigatorChanged(nctLayout);
end;
procedure TcxCustomNavigatorButtons.SetOnButtonClick(
const Value: TcxNavigatorButtonClickEvent);
begin
FOnButtonClick := Value;
Navigator.NavigatorChanged(nctProperties);
end;
procedure TcxCustomNavigatorButtons.ImageListChange(Sender: TObject);
begin
Navigator.RefreshNavigator;
end;
{ TcxNavigatorViewInfo }
constructor TcxNavigatorViewInfo.Create(ANavigator: IcxNavigatorOwner;
AIsInplace: Boolean = True);
begin
inherited Create;
FNavigator := ANavigator;
FIsDirty := True;
FIsInplace := AIsInplace;
FButtons := TList.Create;
FHintWindowShowing := False;
FButtonPressTimer := TcxTimer.Create(nil);
FButtonPressTimer.Enabled := False;
FButtonPressTimer.OnTimer := DoButtonPressTimer;
FHintTimer := TcxTimer.Create(nil);
FHintTimer.Enabled := False;
FHintTimer.Interval := 500;
FHintTimer.OnTimer := DoHintTimer;
FCanvas := TcxCanvas.Create(nil);
end;
destructor TcxNavigatorViewInfo.Destroy;
begin
FreeAndNil(FCanvas);
FreeAndNil(FHintTimer);
FreeAndNil(FButtonPressTimer);
FreeAndNil(FHintWindow);
Clear;
FreeAndNil(FButtons);
inherited Destroy;
end;
procedure TcxNavigatorViewInfo.Calculate;
var
AHeight, AWidth: Integer;
I: Integer;
ANavigatorBounds: TRect;
begin
ANavigatorBounds := Navigator.GetNavigatorBounds;
with ANavigatorBounds do
begin
AWidth := Right - Left;
AHeight := Bottom - Top;
end;
CheckSize(AWidth, AHeight);
for I := 0 to ButtonCount - 1 do
begin
Buttons[I].Enabled := Buttons[I].Button.GetInternalEnabled;
Buttons[I].Hint := Buttons[I].Button.GetInternalHint;
end;
FIsDirty := False;
end;
procedure TcxNavigatorViewInfo.CheckSize(var AWidth, AHeight: Integer;
ACheckMinHeight: Boolean = False);
procedure CheckButtonCount;
var
APButtonViewInfo: TcxNavigatorButtonViewInfo;
AVisibleButtonCount, I: Integer;
begin
AVisibleButtonCount := GetVisibleButtonCount;
if AVisibleButtonCount < FButtons.Count then
for I := 1 to FButtons.Count - AVisibleButtonCount do
begin
TcxNavigatorButtonViewInfo(FButtons[AVisibleButtonCount]).Free;
FButtons.Delete(AVisibleButtonCount);
end
else
for I := FButtons.Count to AVisibleButtonCount - 1 do
begin
APButtonViewInfo := TcxNavigatorButtonViewInfo.Create;
FButtons.Add(APButtonViewInfo);
end;
end;
var
AButtonViewInfo: TcxNavigatorButtonViewInfo;
AButtonVisibleIndex: Integer;
AMinWidth, AMinHeight, ADifX: Integer;
AMinSize: TSize;
ANavigatorBounds, AButtonBounds: TRect;
ANavigatorButtons: TcxCustomNavigatorButtons;
AVisibleButtonCount: Integer;
I: Integer;
AHotTrackButton, APressedButton: TcxNavigatorButton;
begin
ANavigatorBounds := Navigator.GetNavigatorBounds;
FIsDirty := True;
AHotTrackButton := nil;
APressedButton := nil;
if FHotTrackButtonViewInfo <> nil then
AHotTrackButton := FHotTrackButtonViewInfo.Button;
if FPressedButtonViewInfo <> nil then
APressedButton := FPressedButtonViewInfo.Button;
FHotTrackButtonViewInfo := nil;
FPressedButtonViewInfo := nil;
AMinWidth := 0;
AMinHeight := 0;
ANavigatorButtons := Navigator.GetNavigatorButtons;
AVisibleButtonCount := GetVisibleButtonCount;
CheckButtonCount;
AButtonVisibleIndex := 0;
for I := 0 to ANavigatorButtons.ButtonCount - 1 do
if ANavigatorButtons[I].Visible then
begin
AButtonViewInfo := TcxNavigatorButtonViewInfo(FButtons[AButtonVisibleIndex]);
AButtonViewInfo.Button := ANavigatorButtons[I];
if AButtonViewInfo.Button = APressedButton then
FPressedButtonViewInfo := AButtonViewInfo;
if AButtonViewInfo.Button = AHotTrackButton then
FHotTrackButtonViewInfo := AButtonViewInfo;
AMinSize := GetMinButtonSize(AButtonVisibleIndex, AVisibleButtonCount,
ACheckMinHeight);
Inc(AMinWidth, AMinSize.cx);
if AMinHeight < AMinSize.cy then
AMinHeight := AMinSize.cy;
Inc(AButtonVisibleIndex);
end;
ADifX := 0;
if AHeight < AMinHeight then
AHeight := AMinHeight;
if AWidth < AMinWidth then
AWidth := AMinWidth
else
begin
if ButtonCount > 0 then
ADifX := (AWidth - AMinWidth) div ButtonCount;
AWidth := AMinWidth + ADifX * ButtonCount;
end;
AButtonBounds.Right := ANavigatorBounds.Left;
AButtonBounds.Top := ANavigatorBounds.Top;
AButtonBounds.Bottom := AButtonBounds.Top + AHeight;
for I := 0 to ButtonCount - 1 do
begin
AButtonBounds.Left := AButtonBounds.Right;
AButtonBounds.Right := AButtonBounds.Right + GetMinButtonSize(I, AVisibleButtonCount).cx + ADifX;
Buttons[I].Bounds := AButtonBounds;
end;
end;
procedure TcxNavigatorViewInfo.Clear;
var
I: Integer;
begin
FIsDirty := True;
FHotTrackButtonViewInfo := nil;
FPressedButtonViewInfo := nil;
for I := 0 to ButtonCount - 1 do
TcxNavigatorButtonViewInfo(FButtons[I]).Free;
FButtons.Clear;
end;
procedure TcxNavigatorViewInfo.DoEnter;
begin
InvalidateButton(FocusedButton);
UpdateSelected;
end;
procedure TcxNavigatorViewInfo.DoExit;
begin
InvalidateButton(FocusedButton);
UpdateSelected;
end;
function TcxNavigatorViewInfo.GetButtonAt(const pt: TPoint): TcxNavigatorButton;
var
AViewInfo: TcxNavigatorButtonViewInfo;
begin
AViewInfo := GetButtonViewInfoAt(pt);
if AViewInfo <> nil then
Result := AViewInfo.Button
else
Result := nil;
end;
function TcxNavigatorViewInfo.GetButtonViewInfoAt(const pt: TPoint): TcxNavigatorButtonViewInfo;
var
I: Integer;
begin
Result := nil;
for I := 0 to ButtonCount - 1 do
if PtInRect(Buttons[I].Bounds, pt) then
begin
Result := Buttons[I];
Break;
end;
end;
function TcxNavigatorViewInfo.GetButtonViewInfoByButton(
AButton: TcxNavigatorButton): TcxNavigatorButtonViewInfo;
var
I: Integer;
begin
Result := nil;
for I := 0 to ButtonCount - 1 do
if Buttons[I].Button = AButton then
begin
Result := Buttons[I];
break;
end;
end;
procedure TcxNavigatorViewInfo.MakeIsDirty;
begin
FIsDirty := True;
end;
procedure TcxNavigatorViewInfo.MouseDown(X, Y: Integer);
var
AButtonViewInfo: TcxNavigatorButtonViewInfo;
begin
FHintTimer.Enabled := False;
HintActivate(False);
AButtonViewInfo := GetButtonViewInfoAt(Point(X, Y));
if (AButtonViewInfo <> nil)
and (GetButtonState(AButtonViewInfo) <> cxbsDisabled) then
begin
FButtonPressTimer.Interval := cxInitRepeatPause;
FButtonPressTimer.Enabled := True;
PressedButtonViewInfo := AButtonViewInfo;
FocusedButton := AButtonViewInfo;
InvalidateButton(PressedButtonViewInfo);
end;
UpdateSelected;
end;
procedure TcxNavigatorViewInfo.MouseMove(X, Y: Integer);
var
AButtonViewInfo: TcxNavigatorButtonViewInfo;
begin
AButtonViewInfo := GetButtonViewInfoAt(Point(X, Y));
if AButtonViewInfo <> HotTrackButtonViewInfo then
begin
if (HotTrackButtonViewInfo <> nil)
and (GetButtonState(HotTrackButtonViewInfo) <> cxbsDisabled) then
InvalidateButton(HotTrackButtonViewInfo);
FHotTrackButtonViewInfo := AButtonViewInfo;
if (HotTrackButtonViewInfo <> nil)
and (GetButtonState(HotTrackButtonViewInfo) <> cxbsDisabled) then
InvalidateButton(HotTrackButtonViewInfo);
if FHintWindowShowing then
HintActivate(True)
else FHintTimer.Enabled := True;
end;
if HotTrackButtonViewInfo = nil then
HintActivate(False);
UpdateSelected;
end;
procedure TcxNavigatorViewInfo.MouseUp(X, Y: Integer);
var
AButtonViewInfo: TcxNavigatorButtonViewInfo;
begin
FButtonPressTimer.Enabled := False;
AButtonViewInfo := PressedButtonViewInfo;
FPressedButtonViewInfo := nil;
InvalidateButton(AButtonViewInfo);
FHintTimer.Enabled := True;
UpdateSelected;
if (AButtonViewInfo <> nil) and PtInRect(AButtonViewInfo.Bounds, Point(X, Y)) and AButtonViewInfo.Enabled then
AButtonViewInfo.Button.DoClick;
end;
procedure TcxNavigatorViewInfo.Paint;
var
R: TRect;
I: Integer;
ANavigatorControl: TWinControl;
begin
FCanvas.Canvas := Navigator.GetNavigatorCanvas;
if FIsDirty then
Calculate;
for I := 0 to ButtonCount - 1 do
PaintButton(I);
R := Navigator.GetNavigatorBounds;
ANavigatorControl := Navigator.GetNavigatorControl;
Navigator.GetNavigatorLookAndFeel.GetAvailablePainter(totButton).DrawButtonGroupBorder(Canvas,
R, FIsInplace and ANavigatorControl.Enabled, FIsSelected or (not FIsInplace and
(csDesigning in ANavigatorControl.ComponentState) and ANavigatorControl.Enabled));
if FIsInplace then
Canvas.ExcludeClipRect(R);
end;
procedure TcxNavigatorViewInfo.PressArrowKey(ALeftKey: Boolean);
var
AIndex: Integer;
begin
AIndex := FButtons.IndexOf(FocusedButton);
if AIndex < 0 then exit;
if ALeftKey then
begin
if AIndex > 0 then
FocusedButton := Buttons[AIndex - 1];
end else
begin
if AIndex < ButtonCount - 1 then
FocusedButton := Buttons[AIndex + 1];
end;
end;
procedure TcxNavigatorViewInfo.UpdateButtonsEnabled;
var
I: Integer;
begin
for I := 0 to ButtonCount - 1 do
if Buttons[I].Enabled <> Buttons[I].Button.GetInternalEnabled then
begin
Buttons[I].Enabled := not Buttons[I].Enabled;
InvalidateButton(Buttons[I]);
end;
end;
procedure TcxNavigatorViewInfo.InvalidateButton(AButton: TcxNavigatorButtonViewInfo);
var
ANavigatorControl: TWinControl;
begin
if AButton <> nil then
begin
ANavigatorControl := Navigator.GetNavigatorControl;
if ANavigatorControl.HandleAllocated then
Windows.InvalidateRect(ANavigatorControl.Handle,
@(AButton.Bounds), False);
end;
end;
procedure TcxNavigatorViewInfo.PaintButton(AButtonIndex: Integer);
procedure DrawButtonGlyph(ACanvas: TcxCanvas; const AGlyphRect: TRect);
var
AButton: TcxNavigatorButtonViewInfo;
AButtonState: TcxButtonState;
APainter: TcxCustomLookAndFeelPainterClass;
begin
AButton := TcxNavigatorButtonViewInfo(FButtons[AButtonIndex]);
AButtonState := GetButtonState(AButton);
APainter := Navigator.GetNavigatorLookAndFeel.GetAvailablePainter(totButton);
APainter.DrawNavigatorGlyph(ACanvas, AButton.Button.InternalImages,
AButton.Button.InternalImageIndex, AButtonIndex, AGlyphRect,
AButtonState <> cxbsDisabled, AButton.Button.IsUserImageListUsed);
end;
var
ABitmap: TcxBitmap;
AButton: TcxNavigatorButtonViewInfo;
AButtonBounds, AContentRect, AImageRect, R1: TRect;
AButtonState: TcxButtonState;
AImageSize: TSize;
APainter: TcxCustomLookAndFeelPainterClass;
ACanvas: TcxCanvas;
begin
AButton := TcxNavigatorButtonViewInfo(FButtons[AButtonIndex]);
AButtonBounds := AButton.Bounds;
if not Canvas.RectVisible(AButtonBounds) then
Exit;
AButtonState := GetButtonState(AButton);
APainter := Navigator.GetNavigatorLookAndFeel.GetAvailablePainter(totButton);
AButtonBounds := APainter.AdjustGroupButtonDisplayRect(AButtonBounds, FButtons.Count, AButtonIndex);
AImageSize := AButton.Button.GetImageSize;
AContentRect := AButtonBounds;
ExtendRect(AContentRect, GetButtonBorderExtent(APainter, AButtonIndex, FButtons.Count));
with AContentRect do
begin
AImageRect.Left := Left + (Right - Left - AImageSize.cx) div 2;
AImageRect.Top := Top + (Bottom - Top - AImageSize.cy) div 2;
AImageRect.Right := AImageRect.Left + AImageSize.cx;
AImageRect.Bottom := AImageRect.Top + AImageSize.cy;
if GetButtonState(AButton) = cxbsPressed then
OffsetRect(AImageRect, 1, 1);
end;
ABitmap := TcxBitmap.CreateSize(AButtonBounds, pf32bit);
try
ACanvas := ABitmap.cxCanvas;
cxDrawTransparentControlBackground(Navigator.GetNavigatorControl, ACanvas,
AButtonBounds);
APainter.DrawButtonInGroup(ACanvas, ABitmap.ClientRect,
AButtonState, FButtons.Count, AButtonIndex, clWindow);
R1 := AImageRect;
OffsetRect(R1, - AButtonBounds.Left, - AButtonBounds.Top);
DrawButtonGlyph(ACanvas, R1);
cxBitBlt(Canvas.Handle, ACanvas.Handle, AButtonBounds, cxNullPoint, SRCCOPY);
if Navigator.GetNavigatorTabStop and (AButton = FocusedButton) and
Navigator.GetNavigatorFocused
then
Canvas.DrawFocusRect(AImageRect);
if APainter = TcxWinXPLookAndFeelPainter then
Canvas.ExcludeClipRect(AButton.Bounds);
finally
FreeAndNil(ABitmap);
end;
end;
procedure TcxNavigatorViewInfo.HintActivate(AShow: Boolean);
function NeedShowHint(const AHint: string): Boolean;
begin
Result := AShow and Navigator.GetNavigatorShowHint and (AHint <> '') and
CanShowHint(Navigator.GetNavigatorControl);
end;
var
AHint: string;
P: TPoint;
R: TRect;
begin
if FHintWindow <> nil then
begin
FHintWindow.Hide;
if IsWindowVisible(FHintWindow.Handle) then
ShowWindow(FHintWindow.Handle, SW_HIDE);
FreeAndNil(FHintWindow);
end;
FHintTimer.Enabled := False;
FHintWindowShowing := False;
if (HotTrackButtonViewInfo <> nil) then
AHint := GetShortHint(HotTrackButtonViewInfo.Hint)
else
AHint := '';
if NeedShowHint(AHint) then
begin
FHintWindow := HintWindowClass.Create(nil);
P := InternalGetCursorPos;
Inc(P.Y, cxGetCursorSize.cy);
R := FHintWindow.CalcHintRect(Screen.Width, AHint, nil);
R := Rect(P.X, P.Y, P.X + R.Right, P.Y + R.Bottom - R.Top);
FHintWindow.Color := Application.HintColor;
{$IFDEF DELPHI7}
FHintWindow.ParentWindow := Application.Handle; //Bug in delphi7 and higher
{$ENDIF}
cxActivateHint(FHintWindow, R, AHint);
FHintWindowShowing := True;
end;
end;
function TcxNavigatorViewInfo.GetButton(Index: Integer): TcxNavigatorButtonViewInfo;
begin
Result := TcxNavigatorButtonViewInfo(FButtons[Index]);
end;
function TcxNavigatorViewInfo.GetButtonCount: Integer;
begin
Result := FButtons.Count;
end;
function TcxNavigatorViewInfo.GetFocusedButton: TcxNavigatorButtonViewInfo;
begin
if (FFocusedButton <> nil) and not FFocusedButton.Visible then
FFocusedButton := nil;
if (FFocusedButton = nil) and (ButtonCount > 0) then
FFocusedButton := Buttons[0].Button;
if (FFocusedButton <> nil) then
Result := GetButtonViewInfoByButton(FFocusedButton)
else Result := nil;
end;
procedure TcxNavigatorViewInfo.SetFocusedButton(Value: TcxNavigatorButtonViewInfo);
var
AOldButtonViewInfo: TcxNavigatorButtonViewInfo;
begin
AOldButtonViewInfo := GetFocusedButton;
if AOldButtonViewInfo <> Value then
begin
FFocusedButton := Value.Button;
InvalidateButton(AOldButtonViewInfo);
InvalidateButton(Value);
end;
end;
function TcxNavigatorViewInfo.StopButtonPressTimerIfLeftMouseReleased: Boolean;
begin
if not (ssLeft in InternalGetShiftState) then
begin
FButtonPressTimer.Enabled := False;
MouseUp(-1, -1);
Result := True;
end
else
Result := False;
end;
function TcxNavigatorViewInfo.GetButtonBorderExtent(APainter: TcxCustomLookAndFeelPainterClass;
AButtonIndex, AButtonCount: Integer): TRect;
begin
Result := APainter.ButtonGroupBorderSizes(AButtonCount, AButtonIndex);
end;
function TcxNavigatorViewInfo.GetButtonState(AButton: TcxNavigatorButtonViewInfo): TcxButtonState;
begin
Result := cxbsNormal;
if not AButton.Enabled then
Result := cxbsDisabled
else
if (AButton = PressedButtonViewInfo)
and (AButton = HotTrackButtonViewInfo) then
Result := cxbsPressed
else
if AButton = HotTrackButtonViewInfo then
Result := cxbsHot;
end;
function TcxNavigatorViewInfo.GetMiddleButtonBorderExtent(
APainter: TcxCustomLookAndFeelPainterClass): TRect;
begin
Result := APainter.ButtonGroupBorderSizes(3, 1);
end;
function TcxNavigatorViewInfo.GetMinButtonSize(
AButtonIndex, AButtonCount: Integer; AAutoHeight: Boolean = False): TSize;
var
AButtonBorderExtent: TRect;
APainter: TcxCustomLookAndFeelPainterClass;
begin
Result := TcxNavigatorButtonViewInfo(FButtons[AButtonIndex]).Button.GetImageSize;
APainter := Navigator.GetNavigatorLookAndFeel.GetAvailablePainter(totButton);
AButtonBorderExtent := GetMiddleButtonBorderExtent(APainter);
Result.cx := Result.cx + AButtonBorderExtent.Left + AButtonBorderExtent.Right + 1;
if AAutoHeight then
Result.cy := Result.cy + AButtonBorderExtent.Top + AButtonBorderExtent.Bottom + 1
else
Result.cy := AButtonBorderExtent.Top + AButtonBorderExtent.Bottom + 1;
end;
function TcxNavigatorViewInfo.GetVisibleButtonCount: Integer;
var
ANavigatorButtons: TcxCustomNavigatorButtons;
I: Integer;
begin
Result := 0;
ANavigatorButtons := Navigator.GetNavigatorButtons;
for I := 0 to ANavigatorButtons.ButtonCount - 1 do
if ANavigatorButtons[I].Visible then
Inc(Result);
end;
procedure TcxNavigatorViewInfo.DoButtonPressTimer(Sender: TObject);
begin
if StopButtonPressTimerIfLeftMouseReleased then
Exit;
FButtonPressTimer.Interval := cxRepeatPause;
if (HotTrackButtonViewInfo <> nil) and (HotTrackButtonViewInfo = PressedButtonViewInfo) and
PressedButtonViewInfo.Enabled and (PressedButtonViewInfo.Button.DefaultIndex in [NBDI_PRIOR, NBDI_NEXT]) then
try
PressedButtonViewInfo.Button.DoClick;
except
FButtonPressTimer.Enabled := False;
raise;
end;
end;
procedure TcxNavigatorViewInfo.DoHintTimer(Sender: TObject);
begin
HintActivate(True);
end;
procedure TcxNavigatorViewInfo.UpdateSelected;
var
AIsSelected: Boolean;
ANavigatorControl: TWinControl;
R1, R2: TRect;
begin
if not Navigator.GetNavigatorLookAndFeel.Painter.IsButtonHotTrack then
Exit;
ANavigatorControl := Navigator.GetNavigatorControl;
AIsSelected := (HotTrackButtonViewInfo <> nil) or (PressedButtonViewInfo <> nil) or
Navigator.GetNavigatorFocused;
if (AIsSelected <> FIsSelected) and ANavigatorControl.HandleAllocated then
begin
FIsSelected := AIsSelected;
R1 := Navigator.GetNavigatorBounds;
R2 := R1;
InflateRect(R2, -1, -1);
InternalInvalidate(ANavigatorControl.Handle, R1, R2, False);
end;
end;
{ TcxCustomNavigator }
constructor TcxCustomNavigator.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := ControlStyle - [csAcceptsControls, csSetCaption] + [csOpaque];
FButtons := CreateButtons;
FViewInfo := GetViewInfoClass.Create(Self, False);
TabStop := False;
Height := 25;
end;
destructor TcxCustomNavigator.Destroy;
begin
EndMouseTracking(Self);
FreeAndNil(FViewInfo);
FreeAndNil(FButtons);
inherited Destroy;
end;
procedure TcxCustomNavigator.ClickButton(Index: Integer);
begin
CustomButtons.ClickButton(Index);
end;
procedure TcxCustomNavigator.RestoreButtons;
var
I: Integer;
begin
with CustomButtons do
for I := 0 to ButtonCount - 1 do
FButtons[I].FIsVisibleAssigned := False;
InitButtons;
end;
function TcxCustomNavigator.CanFocusOnClick: Boolean;
begin
Result := inherited CanFocusOnClick and TabStop;
end;
function TcxCustomNavigator.CanResize(var NewWidth, NewHeight: Integer): Boolean;
begin
Result := inherited CanResize(NewWidth, NewHeight);
if Result and (FViewInfo <> nil) and HandleAllocated then
FViewInfo.CheckSize(NewWidth, NewHeight);
end;
function TcxCustomNavigator.CreateButtons: TcxCustomNavigatorButtons;
begin
Result := TcxCustomNavigatorButtons.Create(Self);
end;
procedure TcxCustomNavigator.Paint;
begin
FViewInfo.Paint;
end;
procedure TcxCustomNavigator.DoEnter;
begin
inherited DoEnter;
FViewInfo.DoEnter;
end;
procedure TcxCustomNavigator.DoExit;
begin
inherited DoExit;
FViewInfo.DoExit;
end;
procedure TcxCustomNavigator.EnabledChanged;
begin
RefreshNavigator;
end;
procedure TcxCustomNavigator.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if (Key = VK_LEFT) or (Key = VK_RIGHT) then
FViewInfo.PressArrowKey(Key = VK_LEFT);
if (Key = VK_SPACE) and (FViewInfo.FocusedButton <> nil)
and FViewInfo.FocusedButton.Enabled then
FViewInfo.FocusedButton.Button.DoClick;
end;
procedure TcxCustomNavigator.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
inherited MouseDown(Button, Shift, X, Y);
if Button = mbLeft then
FViewInfo.MouseDown(X, Y);
end;
procedure TcxCustomNavigator.MouseEnter(AControl: TControl);
begin
inherited MouseEnter(AControl);
{$IFDEF DELPHI7}
if IsDesigning then
Exit;
{$ENDIF}
BeginMouseTracking(Self, Bounds, Self);
end;
procedure TcxCustomNavigator.MouseLeave(AControl: TControl);
begin
inherited MouseLeave(AControl);
{$IFDEF DELPHI7}
if IsDesigning then
Exit;
{$ENDIF}
EndMouseTracking(Self);
FViewInfo.MouseMove(-1, -1);
end;
procedure TcxCustomNavigator.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
inherited MouseMove(Shift, X, Y);
FViewInfo.MouseMove(X, Y);
BeginMouseTracking(Self, Bounds, Self);
end;
procedure TcxCustomNavigator.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
inherited MouseUp(Button, Shift, X, Y);
FViewInfo.MouseUp(X, Y);
end;
procedure TcxCustomNavigator.LookAndFeelChanged(Sender: TcxLookAndFeel;
AChangedValues: TcxLookAndFeelValues);
begin
inherited LookAndFeelChanged(Sender, AChangedValues);
RecreateWnd
end;
procedure TcxCustomNavigator.NavigatorMouseLeave;
begin
FViewInfo.MouseMove(-1, -1);
// FViewInfo.FHintWindow.Free;
// FViewInfo.FHintWindow := THintWindow.Create(nil);
end;
procedure TcxCustomNavigator.NavigatorChanged(AChangeType: TcxNavigatorChangeType);
begin
end;
function TcxCustomNavigator.GetNavigatorBounds: TRect;
begin
Result := Rect(0, 0, ClientWidth, ClientHeight);
end;
function TcxCustomNavigator.GetNavigatorButtons: TcxCustomNavigatorButtons;
begin
Result := CustomButtons;
end;
function TcxCustomNavigator.GetNavigatorCanvas: TCanvas;
begin
Result := Canvas.Canvas;
end;
function TcxCustomNavigator.GetNavigatorControl: TWinControl;
begin
Result := Self;
end;
function TcxCustomNavigator.GetNavigatorLookAndFeel: TcxLookAndFeel;
begin
Result := LookAndFeel;
end;
function TcxCustomNavigator.GetNavigatorFocused: Boolean;
begin
Result := Focused;
end;
function TcxCustomNavigator.GetNavigatorShowHint: Boolean;
begin
Result := ShowHint;
end;
function TcxCustomNavigator.GetNavigatorTabStop: Boolean;
begin
Result := TabStop;
end;
function TcxCustomNavigator.GetViewInfoClass: TcxNavigatorViewInfoClass;
begin
Result := TcxNavigatorViewInfo;
end;
procedure TcxCustomNavigator.InitButtons;
var
I: Integer;
begin
for I := 0 to FButtons.ButtonCount - 1 do
FButtons[I].RestoreDefaultVisible(True);
end;
function TcxCustomNavigator.GetNavigatorOwner: TComponent;
begin
Result := Self;
end;
procedure TcxCustomNavigator.NavigatorButtonsStateChanged;
begin
FViewInfo.UpdateButtonsEnabled;
end;
procedure TcxCustomNavigator.RefreshNavigator;
var
AWidth, AHeight: Integer;
begin
if not HandleAllocated then
Exit;
AWidth := Width;
AHeight := Height;
FViewInfo.CheckSize(AWidth, AHeight);
if (AWidth <> Width) or (Height <> AHeight) then
SetBounds(Left, Top, AWidth, AHeight)
else
Invalidate;
end;
procedure TcxCustomNavigator.CreateWnd;
begin
inherited CreateWnd;
RefreshNavigator;
end;
procedure TcxCustomNavigator.WndProc(var Message: TMessage);
begin
if (FViewInfo <> nil) and (FViewInfo.FHintWindowShowing) then
with Message do
if ((Msg >= WM_KEYFIRST) and (Msg <= WM_KEYLAST)) or
((Msg = CM_ACTIVATE) or (Msg = CM_DEACTIVATE)) or
(Msg = CM_APPKEYDOWN) or (Msg = CM_APPSYSCOMMAND) or
(Msg = WM_COMMAND) or ((Msg > WM_MOUSEMOVE) and
(Msg <= WM_MOUSELAST)) or (Msg = WM_NCMOUSEMOVE) then
FViewInfo.HintActivate(False);
inherited WndProc(Message);
end;
procedure TcxCustomNavigator.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
Message.Result := DLGC_WANTARROWS;
end;
procedure TcxCustomNavigator.CMEnabledChanged(var Message: TMessage);
begin
inherited;
EnabledChanged;
end;
procedure TcxCustomNavigator.CMHintShow(var Message: TCMHintShow);
begin
Message.Result := 1;
end;
{ TcxNavigatorControlNotifier }
constructor TcxNavigatorControlNotifier.Create;
begin
inherited Create;
FList := TList.Create;
end;
destructor TcxNavigatorControlNotifier.Destroy;
begin
FreeAndNil(FList);
inherited Destroy;
end;
procedure TcxNavigatorControlNotifier.AddNavigator(ANavigator: IcxNavigatorOwner);
begin
if FList.IndexOf(Pointer(ANavigator)) < 0 then
FList.Add(Pointer(ANavigator));
end;
procedure TcxNavigatorControlNotifier.RemoveNavigator(ANavigator: IcxNavigatorOwner);
begin
FList.Remove(Pointer(ANavigator));
end;
procedure TcxNavigatorControlNotifier.RefreshNavigatorButtons;
var
I: Integer;
begin
for I := 0 to FList.Count - 1 do
IcxNavigatorOwner(FList[I]).NavigatorButtonsStateChanged;
end;
{ TcxNavigatorControlButtons }
procedure TcxNavigatorControlButtons.ReleaseBookmark;
var
ANavigatorControl: IcxNavigator;
begin
ANavigatorControl := Control;
if (ANavigatorControl <> nil) and ANavigatorControl.IsBookmarkAvailable then
ANavigatorControl.ClearBookmark;
end;
function TcxNavigatorControlButtons.GetControl: IcxNavigator;
begin
if Assigned(FOnGetControl) then
Result := FOnGetControl
else
Result := nil;
end;
procedure TcxNavigatorControlButtons.DoButtonClick(ADefaultIndex: Integer);
var
ANavigatorControl: IcxNavigator;
begin
ANavigatorControl := Control;
if (ANavigatorControl <> nil) and ((ADefaultIndex <> NBDI_DELETE) or not ConfirmDelete or
((MessageDlg(cxGetResourceString(@cxNavigator_DeleteRecordQuestion),
mtConfirmation, mbOKCancel, 0) = ID_OK))) then
ANavigatorControl.DoAction(ADefaultIndex);
FNavigator.NavigatorButtonsStateChanged;
end;
function TcxNavigatorControlButtons.GetButtonEnabled(ADefaultIndex: Integer): Boolean;
var
ANavigatorControl: IcxNavigator;
begin
ANavigatorControl := Control;
Result := (ANavigatorControl <> nil) and IsNavigatorEnabled and
(ANavigatorControl.IsActive or (ADefaultIndex = NBDI_FILTER));
if Result then
case ADefaultIndex of
NBDI_FIRST, NBDI_PRIOR, NBDI_PRIORPAGE:
Result := not ANavigatorControl.IsBof;
NBDI_LAST, NBDI_NEXT, NBDI_NEXTPAGE:
Result := not ANavigatorControl.IsEof;
NBDI_INSERT:
Result := ANavigatorControl.CanInsert;
NBDI_APPEND:
Result := ANavigatorControl.CanAppend;
NBDI_DELETE:
Result := ANavigatorControl.CanDelete;
NBDI_EDIT:
Result := ANavigatorControl.CanEdit and not ANavigatorControl.IsEditing;
NBDI_POST, NBDI_CANCEL:
Result := ANavigatorControl.IsEditing;
NBDI_GOTOBOOKMARK:
Result := ANavigatorControl.IsBookmarkAvailable;
end;
end;
{ TcxCustomNavigatorControl }
destructor TcxCustomNavigatorControl.Destroy;
begin
Control := nil;
inherited Destroy;
end;
function TcxCustomNavigatorControl.CreateButtons: TcxCustomNavigatorButtons;
begin
Result := GetButtonsClass.Create(Self);
TcxNavigatorControlButtons(Result).OnGetControl := GetControl;
end;
function TcxCustomNavigatorControl.GetButtonsClass: TcxNavigatorControlButtonsClass;
begin
Result := TcxNavigatorControlButtons;
end;
procedure TcxCustomNavigatorControl.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = Control) then
Control := nil;
end;
procedure TcxCustomNavigatorControl.InitButtons;
var
ANavigator: IcxNavigator;
I: Integer;
begin
if FControl = nil then
begin
for I := 0 to FButtons.ButtonCount - 1 do
FButtons[I].RestoreDefaultVisible(True);
end
else
begin
Supports(FControl, IcxNavigator, ANavigator);
for I := 0 to FButtons.ButtonCount - 1 do
FButtons[I].RestoreDefaultVisible(ANavigator.IsActionSupported(FButtons[I].DefaultIndex));
end;
end;
function TcxCustomNavigatorControl.GetButtons: TcxNavigatorControlButtons;
begin
Result := TcxNavigatorControlButtons(CustomButtons);
end;
function TcxCustomNavigatorControl.GetControl: IcxNavigator;
begin
if Control <> nil then
Supports(Control, IcxNavigator, Result)
else
Result := nil;
end;
procedure TcxCustomNavigatorControl.SetButtons(Value: TcxNavigatorControlButtons);
begin
CustomButtons.Assign(Value);
end;
procedure TcxCustomNavigatorControl.SetControl(Value: TComponent);
var
ANavigator: IcxNavigator;
begin
if (Value <> FControl) and ((Value = nil) or Supports(Value, IcxNavigator,
ANavigator)) then
begin
if FControl <> nil then
begin
{$IFDEF DELPHI5}
FControl.RemoveFreeNotification(Self);
{$ENDIF}
Supports(FControl, IcxNavigator, ANavigator);
if ANavigator.GetNotifier <> nil then
ANavigator.GetNotifier.RemoveNavigator(Self);
end;
FControl := Value;
if (FControl <> nil) then
begin
FControl.FreeNotification(Self);
Supports(FControl, IcxNavigator, ANavigator);
if ANavigator.GetNotifier <> nil then
ANavigator.GetNotifier.AddNavigator(Self);
end;
InitButtons;
RefreshNavigator;
end;
end;
initialization
finalization
FreeAndNil(FNavigatorImages);
end.