git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@38 05c56307-c608-d34a-929d-697000501d7a
5508 lines
162 KiB
ObjectPascal
5508 lines
162 KiB
ObjectPascal
|
|
{*******************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ Express side bar control }
|
|
{ }
|
|
{ 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 EXPRESSBARS 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 dxsbar;
|
|
|
|
{$I cxVer.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF DELPHI4}
|
|
ImgList, ActnList,
|
|
{$ENDIF}
|
|
{$IFDEF DELPHI6}
|
|
Types,
|
|
{$ENDIF}
|
|
Classes, Controls, Windows, SysUtils, ExtCtrls, Graphics, Buttons,
|
|
StdCtrls, Forms, Messages, Menus, CommCtrl;
|
|
|
|
type
|
|
TdxSideBarStore = class;
|
|
TdxStoredSideItem = class;
|
|
TdxSideBarItem = class;
|
|
TdxSideBarTag = Integer;
|
|
|
|
TdxSideBarItemClickEvent = procedure(Sender: TObject; Item: TdxSideBarItem) of object;
|
|
|
|
{$IFDEF DELPHI4}
|
|
TdxSideBarItemActionLink = class(TActionLink)
|
|
protected
|
|
FClient: TdxStoredSideItem;
|
|
|
|
procedure AssignClient(AClient: TObject); override;
|
|
|
|
function IsCaptionLinked: Boolean; override;
|
|
function IsEnabledLinked: Boolean; override;
|
|
function IsHintLinked: Boolean; override;
|
|
function IsImageIndexLinked: Boolean; override;
|
|
|
|
procedure SetCaption(const Value: string); override;
|
|
procedure SetEnabled(Value: Boolean); override;
|
|
procedure SetHint(const Value: string); override;
|
|
procedure SetImageIndex(Value: Integer); override;
|
|
procedure SetVisible(Value: Boolean); override;
|
|
end;
|
|
|
|
TdxSideBarItemActionLinkClass = class of TdxSideBarItemActionLink;
|
|
{$ENDIF}
|
|
|
|
TdxStoredSideItem = class(TComponent)
|
|
private
|
|
FCategory: Integer;
|
|
FCaption: string;
|
|
FEnabled: Boolean;
|
|
FHint: string;
|
|
FLargeImage: Integer;
|
|
FSmallImage: Integer;
|
|
FOnClick: TdxSideBarItemClickEvent;
|
|
FStore: TdxSideBarStore;
|
|
FPopupMenu: TPopupMenu;
|
|
FAvailableInCustomizeForm: Boolean;
|
|
{$IFDEF DELPHI4}
|
|
FActionLink: TdxSideBarItemActionLink;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF DELPHI4}
|
|
function GetAction: TBasicAction;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF DELPHI4}
|
|
procedure SetAction(Value: TBasicAction);
|
|
{$ENDIF}
|
|
procedure SetCaption(Value: string);
|
|
procedure SetCategory(Value: Integer);
|
|
procedure SetEnabled(Value: Boolean);
|
|
procedure SetHint(Value: string);
|
|
procedure SetLargeImage(Value: Integer);
|
|
procedure SetSmallImage(Value: Integer);
|
|
procedure SetStore(Value: TdxSideBarStore);
|
|
|
|
{$IFDEF DELPHI4}
|
|
procedure DoActionChange(Sender: TObject);
|
|
function IsCaptionStored: Boolean;
|
|
function IsEnabledStored: Boolean;
|
|
function IsHintStored: Boolean;
|
|
function IsImageIndexStored: Boolean;
|
|
{$ENDIF}
|
|
protected
|
|
procedure DoClick(Sender: TObject; Item: TdxSideBarItem);
|
|
procedure ReadState(Reader: TReader); override;
|
|
{$IFDEF DELPHI4}
|
|
procedure Loaded; override;
|
|
{$ENDIF}
|
|
procedure Notification(AComponent: TComponent;
|
|
Operation: TOperation); override;
|
|
|
|
{$IFDEF DELPHI4}
|
|
procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); dynamic;
|
|
function GetActionLinkClass: TdxSideBarItemActionLinkClass; dynamic;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF DELPHI4}
|
|
property ActionLink: TdxSideBarItemActionLink read FActionLink write FActionLink;
|
|
{$ENDIF}
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure SetParentComponent(AParent: TComponent); override;
|
|
function GetParentComponent: TComponent; override;
|
|
function HasParent: Boolean; override;
|
|
property AvailableInCustomizeForm: Boolean read FAvailableInCustomizeForm write FAvailableInCustomizeForm;
|
|
property Store: TdxSideBarStore read FStore write SetStore;
|
|
published
|
|
{$IFDEF DELPHI4}
|
|
property Action: TBasicAction read GetAction write SetAction;
|
|
{$ENDIF}
|
|
property Caption: string read FCaption write SetCaption {$IFDEF DELPHI4} stored IsCaptionStored{$ENDIF};
|
|
property Category: Integer read FCategory write SetCategory;
|
|
property Enabled: Boolean read FEnabled write SetEnabled {$IFDEF DELPHI4} stored IsEnabledStored{$ENDIF};
|
|
property Hint: string read FHint write SetHint{$IFDEF DELPHI4} stored IsHintStored{$ENDIF};
|
|
property LargeImage: Integer read FLargeImage write SetLargeImage {$IFDEF DELPHI4} stored IsImageIndexStored{$ENDIF};
|
|
property SmallImage: Integer read FSmallImage write SetSmallImage;
|
|
property PopupMenu: TPopupMenu read FPopupMenu write FPopupMenu;
|
|
property OnClick: TdxSideBarItemClickEvent read FOnClick write FOnClick;
|
|
end;
|
|
|
|
TdxSideBar = class;
|
|
|
|
TdxSideBarStoreDesigner = class(TForm)
|
|
protected
|
|
Store: TdxSideBarStore;
|
|
|
|
procedure CloseSideBarStoreEditor; virtual; abstract;
|
|
procedure SideBarStoreEditorUpdate; virtual; abstract;
|
|
procedure SideBarStoreEditorUpdateItem(AItem: TdxStoredSideItem); virtual; abstract;
|
|
end;
|
|
|
|
TdxSideBarStoreCustomizeForm = class(TForm)
|
|
protected
|
|
Store: TdxSideBarStore;
|
|
|
|
procedure BeginCustomizing;
|
|
procedure EndCustomizing;
|
|
end;
|
|
|
|
TdxSideBarStore = class(TComponent)
|
|
private
|
|
FList: TList;
|
|
FBars: TList;
|
|
FCategories: TStrings;
|
|
FLargeImages: TCustomImageList;
|
|
FSmallImages: TCustomImageList;
|
|
FSmallChangeLink: TChangeLink;
|
|
FLargeChangeLink: TChangeLink;
|
|
FDefaultLargeImage: Integer;
|
|
FDefaultSmallImage: Integer;
|
|
FIsCustomizing: Boolean;
|
|
|
|
function GetCount: Integer;
|
|
function GetSideBarCount: Integer;
|
|
function GetItem(Index: Integer): TdxStoredSideItem;
|
|
function GetSideBar(Index: Integer): TdxSideBar;
|
|
procedure SetCategories(Value: TStrings);
|
|
procedure SetDefaultLargeImage(Value: Integer);
|
|
procedure SetDefaultSmallImage(Value: Integer);
|
|
procedure SetImages(AValue: TCustomImageList; var AImageList: TCustomImageList; AChangeLink: TChangeLink);
|
|
procedure SetLargeImages(Value: TCustomImageList);
|
|
procedure SetSmallImages(Value: TCustomImageList);
|
|
procedure DestroyItems;
|
|
procedure OnChangeLink(Sender: TObject);
|
|
procedure RedrawBars;
|
|
procedure RemoveBarItem(StoredItem: TdxStoredSideItem);
|
|
protected
|
|
{$IFDEF DELPHI3}
|
|
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
|
|
{$ELSE}
|
|
procedure GetChildren(Proc: TGetChildProc); override;
|
|
{$ENDIF}
|
|
procedure SetName(const Value: TComponentName); override;
|
|
procedure Notification(AComponent: TComponent;
|
|
Operation: TOperation); override;
|
|
public
|
|
Designer: TdxSideBarStoreDesigner;
|
|
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure AddItem(Item: TdxStoredSideItem);
|
|
procedure ExchangeItems(Item1, Item2: TdxStoredSideItem);
|
|
procedure RemoveItem(Item: TdxStoredSideItem);
|
|
procedure UpdateItem(Item: TdxStoredSideItem);
|
|
function GetCountByCategory(St: string): Integer;
|
|
function GetItemByCategory(St: string; Index: Integer): TdxStoredSideItem;
|
|
function GetItemsByCategory(St: string; List: TList): Integer;
|
|
procedure Customize;
|
|
procedure UpdateEditorItem(Item: TdxStoredSideItem);
|
|
property Count: Integer read GetCount;
|
|
property IsCustomizing: Boolean read FIsCustomizing;
|
|
property Items[Index: Integer]: TdxStoredSideItem read GetItem;
|
|
property SideBarCount: Integer read GetSideBarCount;
|
|
property SideBars[Index: Integer]: TdxSideBar read GetSideBar;
|
|
published
|
|
property Categories: TStrings read FCategories write SetCategories;
|
|
property DefaultLargeImage: Integer read FDefaultLargeImage write SetDefaultLargeImage;
|
|
property DefaultSmallImage: Integer read FDefaultSmallImage write SetDefaultSmallImage;
|
|
property LargeImages: TCustomImageList read FLargeImages write SetLargeImages;
|
|
property SmallImages: TCustomImageList read FSmallImages write SetSmallImages;
|
|
end;
|
|
|
|
TdxSideGroups = class;
|
|
TdxSideGroup = class;
|
|
TdxSideBarItems = class;
|
|
|
|
TdxSideBarItem = class(TCollectionItem)
|
|
private
|
|
FCaption: string;
|
|
FIsDefault: Boolean;
|
|
FLargeImage: Integer;
|
|
FSmallImage: Integer;
|
|
FStoredItem: TdxStoredSideItem;
|
|
FCustomData: string;
|
|
FHint: string;
|
|
FObject: TObject;
|
|
FTag: TdxSideBarTag;
|
|
FEnabled: Boolean;
|
|
|
|
function GetCaption: string;
|
|
function GetEnabled: Boolean;
|
|
function GetHint: string;
|
|
function GetGroup: TdxSideGroup;
|
|
function GetSideBar: TdxSideBar;
|
|
function GetLargeImage: Integer;
|
|
function GetSmallImage: Integer;
|
|
procedure SetCaption(Value: string);
|
|
procedure SetEnabled(Value: Boolean);
|
|
procedure SetHint(Value: string);
|
|
procedure SetIsDefault(Value: Boolean);
|
|
procedure SetLargeImage(Value: Integer);
|
|
procedure SetSmallImage(Value: Integer);
|
|
procedure SetStoredItem(Value: TdxStoredSideItem);
|
|
public
|
|
constructor Create(Collection: TCollection); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
function MakeVisible: Boolean;
|
|
function IsSelected: Boolean;
|
|
function IsFocused: Boolean;
|
|
function IsFullVisible: Boolean;
|
|
function Visible: Boolean;
|
|
|
|
property Enabled: Boolean read GetEnabled write SetEnabled;
|
|
property Group: TdxSideGroup read GetGroup;
|
|
property SideBar: TdxSideBar read GetSideBar;
|
|
property ItemObject: TObject read FObject write FObject;
|
|
published
|
|
property Caption: string read GetCaption write SetCaption;
|
|
property CustomData: string read FCustomData write FCustomData;
|
|
property Hint: string read GetHint write SetHint;
|
|
property Index;
|
|
property IsDefault: Boolean read FIsDefault write SetIsDefault default True;
|
|
property LargeImage: Integer read GetLargeImage write SetLargeImage default -1;
|
|
property SmallImage: Integer read GetSmallImage write SetSmallImage default -1;
|
|
property StoredItem: TdxStoredSideItem read FStoredItem write SetStoredItem;
|
|
property Tag: TdxSideBarTag read FTag write FTag default 0;
|
|
end;
|
|
|
|
TdxSideBarItems = class(TCollection)
|
|
private
|
|
Group: TdxSideGroup;
|
|
SideBar: TdxSideBar;
|
|
|
|
function GetItem(Index: Integer): TdxSideBarItem;
|
|
procedure SetItem(Index: Integer; Value: TdxSideBarItem);
|
|
protected
|
|
procedure Update(Item: TCollectionItem); override;
|
|
public
|
|
constructor Create(AOwner: TdxSideGroup);
|
|
|
|
function Add: TdxSideBarItem;
|
|
property Items[Index: Integer]: TdxSideBarItem read GetItem write SetItem; default;
|
|
end;
|
|
|
|
TdxSideGroupIconType = (dxsgLargeIcon, dxsgSmallIcon);
|
|
|
|
TdxSideGroup = class(TCollectionItem)
|
|
private
|
|
FItems: TdxSideBarItems;
|
|
FTopVisibleItem: Integer;
|
|
FCaption: string;
|
|
FIconType: TdxSideGroupIconType;
|
|
FIsAssigning: Boolean;
|
|
FVisible: Boolean;
|
|
FTag: Integer;
|
|
FDestroying: Boolean;
|
|
|
|
function GetActive: Boolean;
|
|
function GetItemCount: Integer;
|
|
procedure SetCaption(Value: string);
|
|
procedure SetIconType(Value: TdxSideGroupIconType);
|
|
procedure SetItems(Value: TdxSideBarItems);
|
|
procedure SetTopVisibleItem(Value: Integer);
|
|
procedure SetVisible(Value: Boolean);
|
|
public
|
|
constructor Create(Collection: TCollection); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure MakeActive;
|
|
function GetVisibleCount: Integer;
|
|
function SideBar: TdxSideBar;
|
|
|
|
property Active: Boolean read GetActive;
|
|
property ItemCount: Integer read GetItemCount;
|
|
property TopVisibleItem: Integer read FTopVisibleItem write SetTopVisibleItem;
|
|
property Tag: Integer read FTag write FTag;
|
|
published
|
|
property Caption: string read FCaption write SetCaption;
|
|
property Index;
|
|
property IconType: TdxSideGroupIconType read FIconType write SetIconType default dxsgLargeIcon;
|
|
property Items: TdxSideBarItems read FItems write SetItems;
|
|
property Visible: Boolean read FVisible write SetVisible default True;
|
|
end;
|
|
|
|
TdxSideGroups = class(TCollection)
|
|
private
|
|
SideBar: TdxSideBar;
|
|
|
|
function GetItem(Index: Integer): TdxSideGroup;
|
|
function GetVisibleItem(Index: Integer): TdxSideGroup;
|
|
function GetVisibleCount: Integer;
|
|
procedure SetItem(Index: Integer; Value: TdxSideGroup);
|
|
protected
|
|
procedure Update(Item: TCollectionItem); override;
|
|
public
|
|
constructor Create(AOwner: TdxSideBar);
|
|
|
|
function Add: TdxSideGroup;
|
|
property Items[Index: Integer]: TdxSideGroup read GetItem write SetItem; default;
|
|
property VisibleItems[Index: Integer]: TdxSideGroup read GetVisibleItem;
|
|
property VisibleCount: Integer read GetVisibleCount;
|
|
end;
|
|
|
|
TdxSideBarChangeGroupCaptionEvent = procedure(Sender: TObject; Group: TdxSideGroup) of object;
|
|
TdxSideBarDragDropItemEvent = procedure(Sender: TObject; Source, Target: TdxSideBarItem;
|
|
IsCopy: Boolean) of object;
|
|
TdxSideBarDeleteItemEvent = procedure(Sender: TObject; Item: TdxSideBarItem) of object;
|
|
|
|
TdxSideBarFillStyle = (bfsNone, bfsHorz, bfsVert);
|
|
|
|
TdxSideBarBackGround = class(TPersistent)
|
|
private
|
|
FBeginColor: TColor;
|
|
FEndColor: TColor;
|
|
FOnChange: TNotifyEvent;
|
|
FFillStyle: TdxSideBarFillStyle;
|
|
FStep: Integer;
|
|
|
|
procedure SetBeginColor(Value: TColor);
|
|
procedure SetEndColor(Value: TColor);
|
|
procedure SetFillStyle(Value: TdxSideBarFillStyle);
|
|
procedure SetStep(Value: Integer);
|
|
procedure DoChange;
|
|
public
|
|
constructor Create;
|
|
function IsUsed: Boolean;
|
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
|
published
|
|
property BeginColor: TColor read FBeginColor write SetBeginColor default clGrayText;
|
|
property EndColor: TColor read FEndColor write SetEndColor default clGrayText;
|
|
property FillStyle: TdxSideBarFillStyle read FFillStyle write SetFillStyle default bfsNone;
|
|
property Step: Integer read FStep write SetStep default 2;
|
|
end;
|
|
|
|
TdxsbPaintStyle = (sbpsStandard, sbpsFlat, sbpsXP, sbpsW2K);
|
|
|
|
TdxSideBarPainter = class;
|
|
TdxSideBarViewInfo = class;
|
|
|
|
TdxSideGroupViewInfo = class
|
|
private
|
|
FViewInfo: TdxSideBarViewInfo;
|
|
FGroup: TdxSideGroup;
|
|
FRect: TRect;
|
|
|
|
function GetCaption: String;
|
|
function GetPainter: TdxSideBarPainter;
|
|
public
|
|
constructor Create(AViewInfo: TdxSideBarViewInfo; AGroup: TdxSideGroup; ARect: TRect);
|
|
|
|
function Index: Integer;
|
|
|
|
property Group: TdxSideGroup read FGroup;
|
|
property Caption: String read GetCaption;
|
|
property Painter: TdxSideBarPainter read GetPainter;
|
|
property Rect: TRect read FRect;
|
|
property ViewInfo: TdxSideBarViewInfo read FViewInfo;
|
|
end;
|
|
|
|
TdxSideBarDragSourcePosition = (sbdspTop, sbdspBottom, sbdspIn);
|
|
|
|
TdxSideItemViewInfo = class
|
|
private
|
|
FViewInfo: TdxSideBarViewInfo;
|
|
FItem: TdxSideBarItem;
|
|
FImageRect: TRect;
|
|
FCaptionRect: TRect;
|
|
|
|
function GetCaption: String;
|
|
function GetImageIndex: Integer;
|
|
function GetImageList: TCustomImageList;
|
|
function GetPainter: TdxSideBarPainter;
|
|
protected
|
|
function GetBorderRect: TRect; virtual;
|
|
function GetItemRect: TRect; virtual;
|
|
property BorderRect: TRect read GetBorderRect;
|
|
property ItemRect: TRect read GetItemRect;
|
|
public
|
|
constructor Create(AViewInfo: TdxSideBarViewInfo; AItem: TdxSideBarItem; AImageRect, ACaptionRect: TRect);
|
|
|
|
function Index: Integer;
|
|
function IsPartialVisible: Boolean;
|
|
function Bottom: Integer;
|
|
function Top: Integer;
|
|
function FocusedCaptionRect: TRect;
|
|
function GetItemDragSourceSpace(APosition: TdxSideBarDragSourcePosition): TRect;
|
|
|
|
property Caption: String read GetCaption;
|
|
property ImageIndex: Integer read GetImageIndex;
|
|
property ImageList: TCustomImageList read GetImageList;
|
|
property Item: TdxSideBarItem read FItem;
|
|
property Painter: TdxSideBarPainter read GetPainter;
|
|
property CaptionRect: TRect read FCaptionRect;
|
|
property ImageRect: TRect read FImageRect;
|
|
property ViewInfo: TdxSideBarViewInfo read FViewInfo;
|
|
end;
|
|
|
|
TdxSideItemViewInfoClass = class of TdxSideItemViewInfo;
|
|
|
|
TdxSideBarViewInfo = class
|
|
private
|
|
FPainter: TdxSideBarPainter;
|
|
FGroups: TList;
|
|
FItems: TList;
|
|
FIsReady: Boolean;
|
|
FItemsRect: TRect;
|
|
FTopScrollButtonRect: TRect;
|
|
FBottomScrollButtonRect: TRect;
|
|
|
|
function GetGroup(Index: Integer): TdxSideGroupViewInfo;
|
|
function GetItem(Index: Integer): TdxSideItemViewInfo;
|
|
|
|
function GetItemCorrectedCaptionRect(ACaption: String; ARect: TRect): TRect;
|
|
protected
|
|
function CreateGroup(AGroup: TdxSideGroup; ARect: TRect): TdxSideGroupViewInfo; virtual;
|
|
procedure CreateGroups;
|
|
procedure ClearGroups;
|
|
function CreateItemInfo(AItem: TdxSideBarItem; AImageRect, ACaptionRect: TRect): TdxSideItemViewInfo; virtual;
|
|
function CreateItem(AItem: TdxSideBarItem; ATop: Integer): TdxSideItemViewInfo; virtual;
|
|
procedure CreateItems;
|
|
procedure ClearItems;
|
|
function GetGroupHeight: Integer; virtual;
|
|
function GetPaintRect: TRect; virtual;
|
|
function GetGroupOffSet: Integer; virtual;
|
|
function GetBorderOffSet: Integer; virtual;
|
|
function GetSideBarTopItemSpaceHeight: Integer; virtual;
|
|
|
|
function GetItemViewInfo(AItem: TdxSideBarItem): TdxSideItemViewInfo;
|
|
function GetItemImageRect(AItem: TdxSideBarItem; ATop: Integer): TRect;
|
|
function GetItemCaptionRect(AItem: TdxSideBarItem; ATop: Integer; AImageRect: TRect): TRect;
|
|
function GetItemEditRect(AItem: TdxSideBarItem; ACaption: String): TRect;
|
|
|
|
function GetDrawEdgeFlag: Integer;
|
|
|
|
function GetItemHeight: Integer;
|
|
function GetLargeImageHeight: Integer;
|
|
function GetLargeImageWidth: Integer;
|
|
function GetSmallImageHeight: Integer;
|
|
function GetSmallImageWidth: Integer;
|
|
|
|
procedure CalcItemsRect;
|
|
procedure CalcScrollButtonsRect;
|
|
|
|
function GroupIndexOf(AGroup: TdxSideGroupViewInfo): Integer;
|
|
function ItemIndexOf(AItem: TdxSideItemViewInfo): Integer;
|
|
|
|
property ItemsRect: TRect read FItemsRect;
|
|
property TopScrollButtonRect: TRect read FTopScrollButtonRect;
|
|
property BottomScrollButtonRect: TRect read FBottomScrollButtonRect;
|
|
public
|
|
constructor Create(APainter: TdxSideBarPainter); virtual;
|
|
destructor Destroy; override;
|
|
function SideBar: TdxSideBar;
|
|
procedure Clear;
|
|
procedure CalcViewInfo;
|
|
procedure Unready;
|
|
|
|
function GroupCount: Integer;
|
|
function ItemCount: Integer;
|
|
|
|
function GetGroupViewInfoByGroup(AGroup: TdxSideGroup): TdxSideGroupViewInfo;
|
|
function GetItemViewInfoByItem(AItem: TdxSideBarItem): TdxSideItemViewInfo;
|
|
|
|
function ActiveGroupViewInfo: TdxSideGroupViewInfo;
|
|
function GetGroupViewInfoAtPos(p: TPoint): TdxSideGroupViewInfo;
|
|
function GetGroupAtPos(p: TPoint): TdxSideGroup;
|
|
function GetItemViewInfoAtPos(p: TPoint): TdxSideItemViewInfo;
|
|
function GetItemAtPos(p: TPoint): TdxSideBarItem;
|
|
function GetNearestItemViewInfoAtPost(p: TPoint; var APosition: TdxSideBarDragSourcePosition): TdxSideItemViewInfo;
|
|
function GetNearestItemAtPost(p: TPoint; var APosition: TdxSideBarDragSourcePosition): TdxSideBarItem;
|
|
|
|
function IsTopScrollButtonVisible: Boolean;
|
|
function IsBottomScrollButtonVisible: Boolean;
|
|
function IsPtTopScrollButton(pt: TPoint): Boolean;
|
|
function IsPtBottomScrollButton(pt: TPoint): Boolean;
|
|
|
|
property IsReady: Boolean read FIsReady;
|
|
property Painter: TdxSideBarPainter read FPainter;
|
|
property Groups[Index: Integer]: TdxSideGroupViewInfo read GetGroup;
|
|
property Items[Index: Integer]: TdxSideItemViewInfo read GetItem;
|
|
end;
|
|
|
|
TdxSideBarViewInfoClass = class of TdxSideBarViewInfo;
|
|
|
|
TdxSideBarPainter = class
|
|
private
|
|
FSideBar: TdxSideBar;
|
|
FViewInfo: TdxSideBarViewInfo;
|
|
protected
|
|
function ClientHeight: Integer;
|
|
function ClientWidth: Integer;
|
|
procedure ExcludeClipRect(ARect: TRect);
|
|
procedure IntersectClipRect(ARect: TRect);
|
|
|
|
function CreateViewInfo: TdxSideBarViewInfo; virtual;
|
|
|
|
procedure ScrollGroups;
|
|
|
|
procedure DoDrawItemBorder(AItemViewInfo: TdxSideItemViewInfo; const ARect: TRect); virtual;
|
|
|
|
procedure DrawFillRect(ARect: TRect);
|
|
procedure DrawGroups;
|
|
procedure DrawItems;
|
|
procedure DrawBorder; virtual;
|
|
procedure DrawGroup(AGroupViewInfo: TdxSideGroupViewInfo); virtual;
|
|
procedure DrawItem(AItemViewInfo: TdxSideItemViewInfo); virtual;
|
|
procedure DrawItemCaption(AItemViewInfo: TdxSideItemViewInfo); virtual;
|
|
procedure DrawImageBackground(AItemViewInfo: TdxSideItemViewInfo; ARect: TRect); virtual;
|
|
procedure DrawItemImage(AItemViewInfo: TdxSideItemViewInfo); virtual;
|
|
procedure DrawItemBorder(AItemViewInfo: TdxSideItemViewInfo); virtual;
|
|
procedure DrawScrollButtons; virtual;
|
|
procedure DrawDragDestinationArrow; virtual;
|
|
public
|
|
constructor Create(ASideBar: TdxSideBar); virtual;
|
|
destructor Destroy; override;
|
|
function Canvas: TCanvas;
|
|
function DC: HDC;
|
|
procedure NeedRecalViewInfo;
|
|
|
|
procedure Paint;
|
|
procedure InvalidateGroup(AGroup: TdxSideGroup);
|
|
procedure InvalidateItem(AItem: TdxSideBarItem); virtual;
|
|
procedure InvalidateItemImage(AItem: TdxSideBarItem);
|
|
procedure InvalidateItemBorder(AItem: TdxSideBarItem); virtual;
|
|
procedure InvalidateItems;
|
|
procedure InvalidateScrollButtons;
|
|
|
|
function IsGroupFocused: Boolean; virtual;
|
|
|
|
property SideBar: TdxSideBar read FSideBar;
|
|
property ViewInfo: TdxSideBarViewInfo read FViewInfo;
|
|
end;
|
|
|
|
TdxSideBarPainterClass = class of TdxSideBarPainter;
|
|
|
|
TdxSideBar = class(TCustomPanel)
|
|
private
|
|
FLargeImages: TCustomImageList;
|
|
FSmallImages: TCustomImageList;
|
|
FSmallChangeLink: TChangeLink;
|
|
FLargeChangeLink: TChangeLink;
|
|
|
|
FActiveGroupIndex: Integer;
|
|
FOldActiveGroup: TdxSideGroup;
|
|
FActiveGroup: TdxSideGroup;
|
|
FGroups: TdxSideGroups;
|
|
FStore: TdxSideBarStore;
|
|
FGroupFont: TFont;
|
|
FItemFont: TFont;
|
|
FRenameGroup: TdxSideGroup;
|
|
FRenameItem: TdxSideBarItem;
|
|
FRenameEdit: TEdit;
|
|
FCanSelected: Boolean;
|
|
FHintWindow: THintWindow;
|
|
FHintWindowShowing: Boolean;
|
|
// FHintTimerID: Integer;
|
|
FSelectedItem: TdxSideBarItem;
|
|
FOnDeleteItem: TdxSideBarDeleteItemEvent;
|
|
FOnChangeActiveGroup: TNotifyEvent;
|
|
FOnChangeFocusedItem: TNotifyEvent;
|
|
FOnChangeSelectedItem: TNotifyEvent;
|
|
FOnChangeGroupCaption: TdxSideBarChangeGroupCaptionEvent;
|
|
FSpaceHeight: Integer;
|
|
FScrollButtonUpIsDown: Boolean;
|
|
FScrollButtonDownIsDown: Boolean;
|
|
|
|
FScrollTimer: TTimer;
|
|
FHintTimer: TTimer;
|
|
|
|
FMouseDownItem: TdxSideBarItem;
|
|
FMouseFocusedItem: TdxSideBarItem;
|
|
FMouseFocusedItemIsDown: Boolean;
|
|
FMouseFocusedGroup: TdxSideGroup;
|
|
FMouseFocusedGroupIsDown: Boolean;
|
|
FDestDropItem: TdxSideBarItem;
|
|
FDropItemPosition: TdxSideBarDragSourcePosition;
|
|
FEnableDraging: Boolean;
|
|
FDragMode: TDragMode;
|
|
FPointDragging: TPoint;
|
|
FGroupPopupMenu: TPopupMenu;
|
|
FItemPopupMenu: TPopupMenu;
|
|
FTransparentImages: Boolean;
|
|
FImageList: TImageList;
|
|
FAssignFlag: Boolean;
|
|
FOnMouseEnter: TNotifyEvent;
|
|
FOnMouseLeave: TNotifyEvent;
|
|
FOnAfterEdit: TNotifyEvent;
|
|
FOnBeforeEdit: TNotifyEvent;
|
|
FOnDragDropItem: TdxSideBarDragDropItemEvent;
|
|
FOnItemClick: TdxSideBarItemClickEvent;
|
|
FBkPicture: TPicture;
|
|
FBkGround: TdxSideBarBackGround;
|
|
FPaintStyle: TdxsbPaintStyle;
|
|
FRegistryPath: string;
|
|
FStoreInRegistry: Boolean;
|
|
FIsMakingUpdate: Boolean;
|
|
FGroupHeightOffSet: Integer;
|
|
FShowGroups: Boolean;
|
|
FDestroying: Boolean;
|
|
FPainter: TdxSideBarPainter;
|
|
|
|
function GetGroupCount: Integer;
|
|
function GetHintWindow: THintWindow;
|
|
function GetPainter: TdxSideBarPainter;
|
|
function GetScrollDelay: Integer;
|
|
function GetViewInfo: TdxSideBarViewInfo;
|
|
procedure SetActiveGroup(Value: TdxSideGroup);
|
|
procedure SetActiveGroupIndex(Value: Integer);
|
|
procedure SetBkGround(Value: TdxSideBarBackGround);
|
|
procedure SetBkPicture(Value: TPicture);
|
|
procedure SetCanSelected(Value: Boolean);
|
|
procedure SetGroupFont(Value: TFont);
|
|
procedure SetGroups(Value: TdxSideGroups);
|
|
procedure SetGroupHeightOffSet(Value: Integer);
|
|
procedure SetItemFont(Value: TFont);
|
|
procedure SetImages(AValue: TCustomImageList; var AImageList: TCustomImageList; AChangeLink: TChangeLink);
|
|
procedure SetLargeImages(Value: TCustomImageList);
|
|
procedure SetSmallImages(Value: TCustomImageList);
|
|
procedure SetPaintStyle(Value: TdxsbPaintStyle);
|
|
procedure SetScrollDelay(Value: Integer);
|
|
procedure SetShowGroups(Value: Boolean);
|
|
procedure SetSpaceHeight(Value: Integer);
|
|
procedure SetStore(Value: TdxSideBarStore);
|
|
procedure SetTransparentImages(Value: Boolean);
|
|
procedure SetDestDropItem(Value: TdxSideBarItem);
|
|
procedure SetDropItemPosition(Value: TdxSideBarDragSourcePosition);
|
|
procedure SetDestDropItemandPosition(AItem: TdxSideBarItem; APosition: TdxSideBarDragSourcePosition);
|
|
procedure SetMouseFocusedItem(Item: TdxSideBarItem);
|
|
procedure SetSelectedItem(Item: TdxSideBarItem);
|
|
|
|
procedure DoHintTimer(Sender: TObject);
|
|
procedure DoScrollTimer(Sender: TObject);
|
|
procedure HintActivate(AShow: Boolean);
|
|
|
|
function GetVisibleGroup(Index: Integer): TdxSideGroup;
|
|
function GetVisibleIndexByGroup(AGroup: TdxSideGroup): Integer;
|
|
|
|
function GetFocusedItem(X, Y: Integer): TdxSideBarItem;
|
|
function GetTopVisibleToMakeItemVisible(AItem: TdxSideBarItem): Integer;
|
|
function GetDestDropItemViewInfo: TdxSideItemViewInfo;
|
|
|
|
procedure RenameEditExit(Sender: TObject);
|
|
procedure DoGroupMouseFocused(Group: TdxSideGroup; IsDown: Boolean);
|
|
procedure DoItemMouseFocused(Item: TdxSideBarItem; IsDown: Boolean);
|
|
procedure DoItemSelected(Item: TdxSideBarItem);
|
|
procedure DoBkPictureChange(Sender: TObject);
|
|
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
|
|
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
|
|
procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
|
|
procedure WMSetCursor(var Message: TWMSetCursor); message WM_SETCURSOR;
|
|
procedure WMSize(var Message: TWMSize); message WM_SIZE;
|
|
|
|
procedure OnChangeLink(Sender: TObject);
|
|
procedure OnFontChange(Sender: TObject);
|
|
protected
|
|
procedure Loaded; override;
|
|
procedure Paint; override;
|
|
procedure RepaintAll;
|
|
procedure InvalidateGroup(AGroup: TdxSideGroup);
|
|
procedure InvalidateItem(AItem: TdxSideBarItem);
|
|
procedure InvalidateItemImage(AItem: TdxSideBarItem);
|
|
procedure InvalidateItemBorder(AItem: TdxSideBarItem);
|
|
procedure InvalidateItems(AUpdateCalcInfo: Boolean);
|
|
procedure InvalidateScrollButtons;
|
|
|
|
procedure WndProc(var Message: TMessage); override;
|
|
procedure Notification(AComponent: TComponent;
|
|
Operation: TOperation); override;
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); override;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
procedure DoItemClick(Item: TdxSideBarItem); virtual;
|
|
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState;
|
|
var Accept: Boolean); override;
|
|
procedure DoEndDrag(Target: TObject; X, Y: Integer); override;
|
|
procedure DoStartDrag(var DragObject: TDragObject); override;
|
|
function CreatePainter: TdxSideBarPainter; virtual;
|
|
function VisibleGroupCount: Integer;
|
|
|
|
property DestDropItem: TdxSideBarItem read FDestDropItem write SetDestDropItem;
|
|
property DestDropItemViewInfo: TdxSideItemViewInfo read GetDestDropItemViewInfo;
|
|
property DropItemPosition: TdxSideBarDragSourcePosition read FDropItemPosition write SetDropItemPosition;
|
|
property HintWindow: THintWindow read GetHintWindow;
|
|
property MouseFocusedItemIsDown: Boolean read FMouseFocusedItemIsDown;
|
|
property Painter: TdxSideBarPainter read GetPainter;
|
|
property ViewInfo: TdxSideBarViewInfo read GetViewInfo;
|
|
property VisibleGroups[Index: Integer]: TdxSideGroup read GetVisibleGroup;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
|
|
|
|
class function XPBackgroundColor: COLORREF;
|
|
class function XPSelectedItemColor: COLORREF;
|
|
|
|
procedure Assign(Source: TPersistent); override;
|
|
function GetGroupAtPos(p: TPoint): TdxSideGroup;
|
|
function GetItemAtPos(p: TPoint): TdxSideBarItem;
|
|
function GetPopupGroup: TdxSideGroup;
|
|
function IsGroupEditing: Boolean;
|
|
function IsItemEditing: Boolean;
|
|
function IsEditing: Boolean;
|
|
procedure EditGroup(Group: TdxSideGroup);
|
|
procedure EditItem(Item: TdxSideBarItem);
|
|
procedure EndEdit(Accept: Boolean);
|
|
|
|
function GetSmallImages: TCustomImageList;
|
|
function GetLargeImages: TCustomImageList;
|
|
|
|
procedure LoadFromRegistry(ARegistryPath: string);
|
|
procedure SaveToRegistry(ARegistryPath: string);
|
|
|
|
property ActiveGroup: TdxSideGroup read FActiveGroup write SetActiveGroup;
|
|
property EditControl: TEdit read FRenameEdit;
|
|
property EditingGroup: TdxSideGroup read FRenameGroup;
|
|
property EditingItem: TdxSideBarItem read FRenameItem;
|
|
property FocusedItem: TdxSideBarItem read FMouseFocusedItem;
|
|
property GroupCount: Integer read GetGroupCount;
|
|
property IsMakingUpdate: Boolean read FIsMakingUpdate write FIsMakingUpdate;
|
|
property SelectedItem: TdxSideBarItem read FSelectedItem write DoItemSelected;
|
|
|
|
property BevelWidth;
|
|
property BorderWidth;
|
|
published
|
|
property Align default alLeft;
|
|
property BkGround: TdxSideBarBackGround read FBkGround write SetBkGround;
|
|
property BkPicture: TPicture read FBkPicture write SetBkPicture;
|
|
property Color default clGrayText;
|
|
property CanSelected: Boolean read FCanSelected write SetCanSelected default False;
|
|
property GroupFont: TFont read FGroupFont write SetGroupFont;
|
|
property Groups: TdxSideGroups read FGroups write SetGroups;
|
|
// Have to be defined after property Groups !
|
|
property ActiveGroupIndex: Integer read FActiveGroupIndex write SetActiveGroupIndex;
|
|
property GroupPopupMenu: TPopupMenu read FGroupPopupMenu write FGroupPopupMenu;
|
|
property GroupHeightOffSet: Integer read FGroupHeightOffSet write SetGroupHeightOffSet default 0;
|
|
property ItemFont: TFont read FItemFont write SetItemFont;
|
|
property ItemPopupMenu: TPopupMenu read FItemPopupMenu write FItemPopupMenu;
|
|
property LargeImages: TCustomImageList read FLargeImages write SetLargeImages;
|
|
property PaintStyle: TdxsbPaintStyle read FPaintStyle write SetPaintStyle default sbpsFlat;
|
|
property SmallImages: TCustomImageList read FSmallImages write SetSmallImages;
|
|
property ScrollDelay: Integer read GetScrollDelay write SetScrollDelay default 300;
|
|
property SpaceHeight: Integer read FSpaceHeight write SetSpaceHeight default 7;
|
|
property Store: TdxSideBarStore read FStore write SetStore;
|
|
property TransparentImages: Boolean read FTransparentImages write SetTransparentImages default False;
|
|
property RegistryPath: string read FRegistryPath write FRegistryPath;
|
|
property ShowGroups: Boolean read FShowGroups write SetShowGroups default True;
|
|
property StoreInRegistry: Boolean read FStoreInRegistry write FStoreInRegistry default False;
|
|
property OnItemClick: TdxSideBarItemClickEvent read FOnItemClick write FOnItemClick;
|
|
property OnDeleteItem: TdxSideBarDeleteItemEvent read FOnDeleteItem write FOnDeleteItem;
|
|
property OnChangeActiveGroup: TNotifyEvent read FOnChangeActiveGroup write FOnChangeActiveGroup;
|
|
property OnChangeFocusedItem: TNotifyEvent read FOnChangeFocusedItem write FOnChangeFocusedItem;
|
|
property OnChangeGroupCaption: TdxSideBarChangeGroupCaptionEvent
|
|
read FOnChangeGroupCaption write FOnChangeGroupCaption;
|
|
property OnChangeSelectedItem: TNotifyEvent read FOnChangeSelectedItem
|
|
write FOnChangeSelectedItem;
|
|
property BorderStyle;
|
|
property DragCursor;
|
|
property DragMode read FDragMode write FDragMode;
|
|
property Enabled;
|
|
property Ctl3D;
|
|
property Locked;
|
|
property ParentColor;
|
|
property ParentCtl3D;
|
|
property ParentShowHint;
|
|
property ShowHint;
|
|
property Visible;
|
|
property OnAfterEdit: TNotifyEvent read FOnAfterEdit write FOnAfterEdit;
|
|
property OnBeforeEdit: TNotifyEvent read FOnBeforeEdit write FOnBeforeEdit;
|
|
property OnClick;
|
|
property OnDblClick;
|
|
property OnDragDrop;
|
|
property OnDragDropItem: TdxSideBarDragDropItemEvent read FOnDragDropItem
|
|
write FOnDragDropItem;
|
|
property OnDragOver;
|
|
property OnEndDrag;
|
|
property OnEnter;
|
|
property OnExit;
|
|
property OnMouseDown;
|
|
property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
|
|
property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
property OnResize;
|
|
property OnStartDrag;
|
|
|
|
{$IFDEF DELPHI4}
|
|
property Anchors;
|
|
property Constraints;
|
|
property OnStartDock;
|
|
property OnEndDock;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
TdxSideBarPopupMenuOption = (sbmIconType, sbmAddGroup, sbmRemoveGroup,
|
|
sbmCustomize, sbmRenameGroup, sbmRenameItem, sbmRemoveItem);
|
|
|
|
TdxSideBarPopupMenuOptions = set of TdxSideBarPopupMenuOption;
|
|
|
|
TdxSideBarPopupMenu = class(TPopupMenu)
|
|
private
|
|
FOptions: TdxSideBarPopupMenuOptions;
|
|
List: TList;
|
|
Bar: TdxSideBar;
|
|
FocusedItem: TdxSideBarItem;
|
|
Group: TdxSideGroup;
|
|
FOnAfterClick: TNotifyEvent;
|
|
FOnPopupClose: TNotifyEvent;
|
|
protected
|
|
procedure BarMenuClick(Sender: TObject);
|
|
procedure DestroyBarItems;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
|
|
procedure Popup(X, Y: Integer); override;
|
|
published
|
|
property Options: TdxSideBarPopupMenuOptions read FOptions write FOptions;
|
|
property OnAfterClick: TNotifyEvent read FOnAfterClick write FOnAfterClick;
|
|
property OnPopupClose: TNotifyEvent read FOnPopupClose write FOnPopupClose;
|
|
end;
|
|
|
|
EdxSideBarError = class(Exception);
|
|
|
|
TdxSideBarDragObject = class(TObject)
|
|
private
|
|
FStoredItem: TdxStoredSideItem;
|
|
FItem: TdxSideBarItem;
|
|
FDeleteItem: Boolean;
|
|
FDragObject: TDragControlObject;
|
|
FCancelDrag: Boolean;
|
|
public
|
|
constructor Create(Control: TControl; var DragObject: TDragObject;
|
|
AItem: TdxSideBarItem; AStoredItem: TdxStoredSideItem);
|
|
destructor Destroy; override;
|
|
function EndDrag(Target: TObject; X, Y: Integer): TdxSideBarItem;
|
|
|
|
property CancelDrag: Boolean read FCancelDrag write FCancelDrag;
|
|
property DeleteItem: Boolean read FDeleteItem write FDeleteItem;
|
|
property Item: TdxSideBarItem read FItem;
|
|
property StoredItem: TdxStoredSideItem read FStoredItem;
|
|
end;
|
|
|
|
var
|
|
dxSideBarDragObject: TdxSideBarDragObject;
|
|
|
|
//Group scrolling variable. Change them to change the speed of the group scrolling
|
|
dxSideBarGroupScrollStep: Integer = 1;
|
|
dxSideBarGroupScrollIncrement: Integer = 2;
|
|
dxSideBarGroupScrollTimeToIncrement: Integer = 50;
|
|
|
|
implementation
|
|
|
|
{$R dxsbar.res}
|
|
|
|
uses dxsbstrs, dxsbarcs, Registry, TypInfo, Math;
|
|
|
|
const
|
|
ScrollButtonHeight = 16;
|
|
ScrollButtonIndention = 3;
|
|
|
|
dxSideBarHintShowDelay = 3000;
|
|
|
|
// Cursors
|
|
dxSideBarDragCursor = -1121;
|
|
dxSideBarDragCopyCursor = -1122;
|
|
dxSideBarDragDeleteCursor = -1123;
|
|
dxSideBarGroupCursor = -1125;
|
|
|
|
dxSideBarDefaultLargeImageHeight = 32;
|
|
dxSideBarDefaultLargeImageWidth = 32;
|
|
dxSideBarDefaultSmallImageHeight = 16;
|
|
dxSideBarDefaultSmallImageWidth = 16;
|
|
|
|
dxSideBarDragArrowHeight = 9;
|
|
|
|
function CreateChangeLink(AOnChange: TNotifyEvent): TChangeLink;
|
|
begin
|
|
Result := TChangeLink.Create;
|
|
Result.OnChange := AOnChange;
|
|
end;
|
|
|
|
// null reference routines
|
|
|
|
function GetViewInfoItem(AItemViewInfo: TdxSideItemViewInfo): TdxSideBarItem;
|
|
begin
|
|
if AItemViewInfo <> nil then
|
|
Result := AItemViewInfo.Item
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function GetViewInfoGroup(AGroupViewInfo: TdxSideGroupViewInfo): TdxSideGroup;
|
|
begin
|
|
if AGroupViewInfo <> nil then
|
|
Result := AGroupViewInfo.Group
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure CallNotify(ANotifyEvent: TNotifyEvent; ASender: TObject);
|
|
begin
|
|
if Assigned(ANotifyEvent) then
|
|
ANotifyEvent(ASender);
|
|
end;
|
|
|
|
// cxGraphics
|
|
|
|
function cxDrawText(ADC: THandle; const AText: string; var ARect: TRect; AFormat: UINT; ACharCount: Integer = - 1): Integer;
|
|
begin
|
|
Result := Windows.DrawText(ADC, PChar(AText), ACharCount, ARect, AFormat);
|
|
end;
|
|
|
|
function IsImageAssigned(AImageList: TCustomImageList; AImageIndex: Integer): Boolean;
|
|
begin
|
|
Result := (AImageList <> nil) and (0 <= AImageIndex) and (AImageIndex < AImageList.Count);
|
|
end;
|
|
|
|
procedure cxInvalidateRect(AHandle: THandle; const ARect: TRect; AEraseBackground: Boolean = True);
|
|
begin
|
|
InvalidateRect(AHandle, @ARect, AEraseBackground);
|
|
end;
|
|
|
|
// system routines
|
|
|
|
procedure DrawBmpOnCanvas(ACanvas: TCanvas; APicture: TPicture;
|
|
ADrawRect: TRect; AWidth, AHeight: Integer);
|
|
var
|
|
dLeft, dTop, dWidth, dHeight, sLeft, sTop : Integer;
|
|
ABmp: TBitmap;
|
|
ACreatedFlag: Boolean;
|
|
begin
|
|
ABmp := nil;
|
|
ACreatedFlag := False;
|
|
if (APicture.Graphic is TBitmap) then
|
|
ABmp := APicture.Bitmap;
|
|
if (APicture.Graphic is TIcon) or (APicture.Graphic is TMetaFile) then
|
|
begin
|
|
ABmp := TBitmap.Create;
|
|
ABmp.Height := APicture.Graphic.Height;
|
|
ABmp.Width := APicture.Graphic.Height;
|
|
ABmp.Canvas.Draw(0, 0, APicture.Graphic);
|
|
ACreatedFlag := True;
|
|
end;
|
|
|
|
if (ABmp = nil) then begin
|
|
ACanvas.FillRect(ADrawRect);
|
|
Exit;
|
|
end;
|
|
dTop := ADrawRect.Top;
|
|
while (dTop < ADrawRect.Bottom) do begin
|
|
if (dTop mod ABmp.Height <> 0) then
|
|
sTop := dTop - (dTop div ABmp.Height) * ABmp.Height
|
|
else sTop := 0;
|
|
dHeight := ABmp.Height - sTop;
|
|
if (dTop + dHeight > ADrawRect.Bottom) then
|
|
dHeight := ADrawRect.Bottom - dTop;
|
|
dLeft := ADrawRect.Left;
|
|
while (dLeft < ADrawRect.Right) do begin
|
|
if (dLeft mod ABmp.Width <> 0) then
|
|
sLeft := dLeft - (dLeft div ABmp.Width) * ABmp.Width
|
|
else sLeft := 0;
|
|
dWidth := ABmp.Width - sLeft;
|
|
if (dLeft + dWidth > ADrawRect.Right) then
|
|
dWidth := ADrawRect.Right - dLeft;
|
|
BitBlt(ACanvas.Handle, dLeft, dTop, dWidth, dHeight,
|
|
ABmp.Canvas.Handle, sLeft, sTop, SRCCOPY);
|
|
Inc(dLeft, dWidth);
|
|
end;
|
|
Inc(dTop, dHeight);
|
|
end;
|
|
if ACreatedFlag then
|
|
ABmp.Free;
|
|
end;
|
|
|
|
procedure DrawDifColorsOnCanvas(ACanvas: TCanvas; ABeginColor, AEndColor: TColor;
|
|
cdXY: Integer; AIsHorz: Boolean; ADrawRect: TRect; AWidth, AHeight: Integer);
|
|
var
|
|
r: TRect;
|
|
FBeginColor, FEndColor, FColor: Integer;
|
|
FBeginColorB, FBeginColorG, FBeginColorR: Byte;
|
|
FEndColorB, FEndColorG, FEndColorR: Byte;
|
|
dColorB, dColorG, dColorR: Real;
|
|
FColorB, FColorG, FColorR: Real;
|
|
brh: HBRUSH;
|
|
FHeight: Integer;
|
|
begin
|
|
|
|
FBeginColor := ColorToRGB(ABeginColor);
|
|
FEndColor := ColorToRGB(AEndColor);
|
|
|
|
FBeginColorB := GetBValue(FBeginColor);
|
|
FBeginColorG := GetGValue(FBeginColor);
|
|
FBeginColorR := GetRValue(FBeginColor);
|
|
|
|
FEndColorB := GetBValue(FEndColor);
|
|
FEndColorG := GetGValue(FEndColor);
|
|
FEndColorR := GetRValue(FEndColor);
|
|
|
|
if AIsHorz then
|
|
FHeight := AHeight
|
|
else FHeight := AWidth;
|
|
dColorB := (FEndColorB - FBeginColorB) * cdXY /FHeight;
|
|
dColorG := (FEndColorG - FBeginColorG) * cdXY /FHeight;
|
|
dColorR := (FEndColorR - FBeginColorR) * cdXY /FHeight;
|
|
|
|
r := ADrawRect;
|
|
if AIsHorz then begin
|
|
r.Top := ADrawRect.Top;
|
|
FColorB := FBeginColorB + dColorB * r.Top / cdXY;
|
|
FColorG := FBeginColorG + dColorG * r.Top / cdXY;
|
|
FColorR := FBeginColorR + dColorR * r.Top / cdXY;
|
|
while (r.Top < ADrawRect.Bottom) do begin
|
|
r.Bottom := r.Top + cdXY;
|
|
if (r.Bottom > ADrawRect.Bottom) then
|
|
r.Bottom := ADrawRect.Bottom;
|
|
FColor := {PALETTE}RGB(Trunc(FColorR), Trunc(FColorG), Trunc(FColorB));
|
|
brh := CreateSolidBrush(FColor);
|
|
Windows.FillRect(ACanvas.Handle, r, brh);
|
|
DeleteObject(brh);
|
|
if (r.Top mod cdXY <> 0) then
|
|
Dec(r.Top, r.Top mod cdXY);
|
|
Inc(r.Top, cdXY);
|
|
FColorB := FColorB + dColorB;
|
|
FColorG := FColorG + dColorG;
|
|
FColorR := FColorR + dColorR;
|
|
end;
|
|
end else begin
|
|
r.Left := ADrawRect.Left;
|
|
FColorB := FBeginColorB + dColorB * r.Left / cdXY;
|
|
FColorG := FBeginColorG + dColorG * r.Left / cdXY;
|
|
FColorR := FBeginColorR + dColorR * r.Left / cdXY;
|
|
while (r.Left < ADrawRect.Right) do begin
|
|
r.Right := r.Left + cdXY;
|
|
if (r.Right > ADrawRect.Right) then
|
|
r.Right := ADrawRect.Right;
|
|
FColor := {PALETTE}RGB(Trunc(FColorR), Trunc(FColorG), Trunc(FColorB));
|
|
brh := CreateSolidBrush(FColor);
|
|
Windows.FillRect(ACanvas.Handle, r, brh);
|
|
DeleteObject(brh);
|
|
if (r.Left mod cdXY <> 0) then
|
|
Dec(r.Left, r.Left mod cdXY);
|
|
Inc(r.Left, cdXY);
|
|
FColorB := FColorB + dColorB;
|
|
FColorG := FColorG + dColorG;
|
|
FColorR := FColorR + dColorR;
|
|
end;
|
|
end;
|
|
// ACanvas.Brush.Color := OldColor;
|
|
end;
|
|
|
|
function GetClippedString(DC: HDC; const S: string; Rect: TRect): string;
|
|
var
|
|
Width, Len: Integer;
|
|
Size: TSize;
|
|
begin
|
|
if S = '' then Result := ''
|
|
else
|
|
begin
|
|
Width := Rect.Right - Rect.Left;
|
|
for Len := Length(S) downto 0 do
|
|
begin
|
|
GetTextExtentPoint32(DC, PChar(Copy(S, 1, Len)), Len, Size);
|
|
if Size.cX <= Width then Break;
|
|
end;
|
|
Result := Copy(S, 1, Len);
|
|
end;
|
|
end;
|
|
|
|
function GetFontHeight(AFont: TFont): Integer;
|
|
var
|
|
DC: HDC;
|
|
SaveFont: HFont;
|
|
Metrics: TTextMetric;
|
|
begin
|
|
DC := GetDC(0);
|
|
SaveFont := SelectObject(DC, AFont.Handle);
|
|
GetTextMetrics(DC, Metrics);
|
|
SelectObject(DC, SaveFont);
|
|
ReleaseDC(0, DC);
|
|
Result := Metrics.tmHeight;
|
|
end;
|
|
|
|
type
|
|
{TStoredSideBarItemsStoreStrings}
|
|
TStoredSideBarItemsStoreStrings = class(TStringList)
|
|
private
|
|
Owner: TdxSideBarStore;
|
|
|
|
procedure ChangeCategory(OldCategory, NewCategory: Integer);
|
|
public
|
|
constructor Create(AOwner: TdxSideBarStore);
|
|
procedure Clear; override;
|
|
procedure Delete(Index: Integer); override;
|
|
procedure Insert(Index: Integer; const S: string); override;
|
|
procedure Exchange(Index1, Index2: Integer); override;
|
|
procedure Move(CurIndex, NewIndex: Integer); override;
|
|
end;
|
|
|
|
{TSideBarRenameEdit}
|
|
TSideBarRenameEdit = class(TEdit)
|
|
private
|
|
procedure WMChar(var Message: TWMChar); message WM_CHAR;
|
|
protected
|
|
procedure CreateParams(var Params: TCreateParams); override;
|
|
end;
|
|
|
|
{TdxSideBarStandardPainter}
|
|
TdxSideBarStandardViewInfo = class(TdxSideBarViewInfo)
|
|
protected
|
|
function GetPaintRect: TRect; override;
|
|
end;
|
|
|
|
TdxSideBarStandardPainter = class(TdxSideBarPainter)
|
|
protected
|
|
function CreateViewInfo: TdxSideBarViewInfo; override;
|
|
public
|
|
procedure DrawGroup(AGroupViewInfo: TdxSideGroupViewInfo); override;
|
|
end;
|
|
|
|
{TdxSideBarFlatPainter}
|
|
TdxSideBarFlatViewInfo = class(TdxSideBarViewInfo)
|
|
protected
|
|
function GetGroupHeight: Integer; override;
|
|
function GetPaintRect: TRect; override;
|
|
end;
|
|
|
|
TdxSideBarFlatPainter = class(TdxSideBarPainter)
|
|
protected
|
|
function CreateViewInfo: TdxSideBarViewInfo; override;
|
|
public
|
|
procedure DrawBorder; override;
|
|
procedure DrawGroup(AGroupViewInfo: TdxSideGroupViewInfo); override;
|
|
function IsGroupFocused: Boolean; override;
|
|
end;
|
|
|
|
{TdxSideBarW2KPainter}
|
|
TdxSideItemW2KViewInfo = class(TdxSideItemViewInfo)
|
|
protected
|
|
function GetBorderRect: TRect; override;
|
|
end;
|
|
|
|
TdxSideBarW2KViewInfo = class(TdxSideBarFlatViewInfo)
|
|
protected
|
|
function GetSideBarTopItemSpaceHeight: Integer; override;
|
|
public
|
|
function CreateItemInfo(AItem: TdxSideBarItem; AImageRect, ACaptionRect: TRect): TdxSideItemViewInfo; override;
|
|
end;
|
|
|
|
TdxSideBarW2KPainter = class(TdxSideBarFlatPainter)
|
|
protected
|
|
function CreateViewInfo: TdxSideBarViewInfo; override;
|
|
end;
|
|
|
|
{TdxSideBarXPPainter}
|
|
TdxSideBarXPViewInfo = class(TdxSideBarViewInfo)
|
|
protected
|
|
function GetGroupHeight: Integer; override;
|
|
function GetPaintRect: TRect; override;
|
|
function GetGroupOffSet: Integer; override;
|
|
function GetBorderOffSet: Integer; override;
|
|
end;
|
|
|
|
TdxSideBarXPPainter = class(TdxSideBarPainter)
|
|
protected
|
|
function CreateViewInfo: TdxSideBarViewInfo; override;
|
|
procedure DoDrawItemBorder(AItemViewInfo: TdxSideItemViewInfo; const ARect: TRect); override;
|
|
public
|
|
procedure DrawBorder; override;
|
|
procedure DrawGroup(AGroupViewInfo: TdxSideGroupViewInfo); override;
|
|
procedure DrawImageBackground(AItemViewInfo: TdxSideItemViewInfo; ARect: TRect); override;
|
|
procedure InvalidateItemBorder(AItem: TdxSideBarItem); override;
|
|
function IsGroupFocused: Boolean; override;
|
|
end;
|
|
|
|
{TdxSideBarBackGround}
|
|
constructor TdxSideBarBackGround.Create;
|
|
begin
|
|
inherited Create;
|
|
FBeginColor := clGrayText;
|
|
FEndColor := clGrayText;
|
|
FFillStyle := bfsNone;
|
|
FStep := 2;
|
|
end;
|
|
|
|
function TdxSideBarBackGround.IsUsed: Boolean;
|
|
begin
|
|
Result := (FFillStyle <> bfsNone) and (FBeginColor <> EndColor);
|
|
end;
|
|
|
|
procedure TdxSideBarBackGround.SetBeginColor(Value: TColor);
|
|
begin
|
|
if (FBeginColor <> Value) then begin
|
|
FBeginColor := Value;
|
|
DoChange;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarBackGround.SetEndColor(Value: TColor);
|
|
begin
|
|
if (FEndColor <> Value) then begin
|
|
FEndColor := Value;
|
|
DoChange;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarBackGround.SetFillStyle(Value: TdxSideBarFillStyle);
|
|
begin
|
|
if (FFillStyle <> Value) then begin
|
|
FFillStyle := Value;
|
|
DoChange;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarBackGround.SetStep(Value: Integer);
|
|
begin
|
|
if (Value <> FStep) and (Value > 0) then
|
|
begin
|
|
FStep := Value;
|
|
DoChange;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarBackGround.DoChange;
|
|
begin
|
|
CallNotify(FOnChange, Self);
|
|
end;
|
|
|
|
{$IFNDEF DELPHI7}
|
|
var
|
|
SideBarDragObjectHookKey: HHOOK;
|
|
|
|
function SideBarDragObjectWinProcKey(code: Integer; wparam: WParam; lparam: LParam): LResult; stdcall;
|
|
var
|
|
p: TPoint;
|
|
begin
|
|
if (wparam = VK_CONTROL) then begin
|
|
GetCursorPos(p);
|
|
Windows.ScreenToClient(GetCapture, p);
|
|
SendMessage(GetCapture, LongInt(WM_MOUSEMOVE), MK_LBUTTON, MAKELONG(p.X, p.Y));
|
|
end;
|
|
Result := CallNextHookEx(SideBarDragObjectHookKey, code, wparam, lparam);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{TdxSideBarDragObject}
|
|
type
|
|
TtmpDragObject = class(TDragControlObject)
|
|
protected
|
|
function GetDragCursor(Accepted: Boolean; X, Y: Integer): TCursor; override;
|
|
public
|
|
constructor Create(AControl: TControl); override;
|
|
end;
|
|
|
|
function TtmpDragObject.GetDragCursor(Accepted: Boolean; X, Y: Integer): TCursor;
|
|
var
|
|
wnd: TWinControl;
|
|
begin
|
|
if Accepted then begin
|
|
if dxSideBarDragObject.FDeleteItem then
|
|
Result := dxSideBarDragDeleteCursor
|
|
else
|
|
begin
|
|
wnd := FindVCLWindow(Point(X, Y));
|
|
if not (GetKeyState(VK_CONTROL) < 0) and ((dxSideBarDragObject.Item <> nil) or (wnd = nil) or not (wnd is TdxSideBar)) then
|
|
Result := dxSideBarDragCursor
|
|
else
|
|
Result := dxSideBarDragCopyCursor;
|
|
end
|
|
end
|
|
else
|
|
Result := crNoDrop;
|
|
dxSideBarDragObject.FDeleteItem := False;
|
|
end;
|
|
|
|
constructor TtmpDragObject.Create(AControl: TControl);
|
|
begin
|
|
inherited Create(AControl);
|
|
end;
|
|
|
|
constructor TdxSideBarDragObject.Create(Control: TControl;
|
|
var DragObject: TDragObject; AItem: TdxSideBarItem; AStoredItem: TdxStoredSideItem);
|
|
begin
|
|
inherited Create;
|
|
FDragObject := TtmpDragObject.Create(Control);
|
|
DragObject := FDragObject;
|
|
{$IFNDEF DELPHI7}
|
|
//avoid Delphi bug. Send Mouse move on VK_CONTROL down/up
|
|
SideBarDragObjectHookKey := SetWindowsHookEx(WH_KEYBOARD,
|
|
SideBarDragObjectWinProcKey, 0, GetCurrentThreadId);
|
|
{$ENDIF}
|
|
FItem := AItem;
|
|
if Item <> nil then
|
|
FStoredItem := Item.StoredItem
|
|
else
|
|
FStoredItem := AStoredItem;
|
|
end;
|
|
|
|
destructor TdxSideBarDragObject.Destroy;
|
|
begin
|
|
FDragObject.Free;
|
|
inherited;
|
|
end;
|
|
|
|
function TdxSideBarDragObject.EndDrag(Target: TObject; X, Y: Integer): TdxSideBarItem;
|
|
var
|
|
Index: Integer;
|
|
AItem, AFreeItem: TdxSideBarItem;
|
|
begin
|
|
AItem := nil;
|
|
AFreeItem := FItem;
|
|
if (Target <> nil) and (Target is TdxSideBar) then
|
|
with TdxSideBar(Target) do
|
|
begin
|
|
if not FCancelDrag then
|
|
begin
|
|
if ActiveGroup = nil then
|
|
Groups.Add;
|
|
Index := -1;
|
|
if ActiveGroup.Items.Count = 0 then
|
|
Index := 0;
|
|
if (DestDropItemViewInfo <> nil) then
|
|
Index := DestDropItemViewInfo.Item.Index;
|
|
if (Index > -1) and ((GetKeyState(VK_CONTROL) < 0) or not ((Item <> nil)
|
|
and (ActiveGroup = Item.Group)
|
|
and (Item.Index = Index))) then
|
|
begin
|
|
if not (GetKeyState(VK_CONTROL) < 0) and (Item <> nil) and (ActiveGroup = Item.Group) then
|
|
begin
|
|
AItem := Item;
|
|
AFreeItem := nil;
|
|
end else
|
|
begin
|
|
AItem := ActiveGroup.Items.Add;
|
|
if DropItemPosition = sbdspBottom then
|
|
Inc(Index);
|
|
if (dxSideBarDragObject.Item <> nil) then
|
|
AItem.Assign(dxSideBarDragObject.Item)
|
|
else AItem.StoredItem := dxSideBarDragObject.StoredItem;
|
|
end;
|
|
AItem.Index := Index;
|
|
end
|
|
else
|
|
Index := -1;
|
|
FDestDropItem := nil;
|
|
FDropItemPosition := sbdspIn;
|
|
|
|
if (Assigned(FOnDragDropItem)) then
|
|
FOnDragDropItem(Self, Item, AItem, (GetKeyState(VK_CONTROL) < 0));
|
|
|
|
if (AItem <> nil) then
|
|
DoItemSelected(AItem);
|
|
if (AFreeItem <> nil) and (Index > -1) and not (GetKeyState(VK_CONTROL) < 0) then
|
|
AFreeItem.Free;
|
|
FMouseFocusedItem := nil;
|
|
end;
|
|
RepaintAll;
|
|
end;
|
|
|
|
{$IFNDEF DELPHI7}
|
|
UnhookWindowsHookEx(SideBarDragObjectHookKey);
|
|
{$ENDIF}
|
|
Result := AItem;
|
|
Self.Free;
|
|
dxSideBarDragObject := nil;
|
|
end;
|
|
|
|
{TdxSideBarItem}
|
|
constructor TdxSideBarItem.Create(Collection: TCollection);
|
|
begin
|
|
inherited Create(Collection);
|
|
FIsDefault := True;
|
|
FEnabled := True;
|
|
FLargeImage := -1;
|
|
FSmallImage := -1;
|
|
end;
|
|
|
|
destructor TdxSideBarItem.Destroy;
|
|
var
|
|
IsSelectedFlag: Boolean;
|
|
NeedRepaint: Boolean;
|
|
Bar: TdxSideBar;
|
|
begin
|
|
IsSelectedFlag := False;
|
|
NeedRepaint := False;
|
|
Bar := SideBar;
|
|
if (Bar <> nil) and not (csDestroying in Bar.ComponentState) then begin
|
|
NeedRepaint := Visible and not Bar.FDestroying;
|
|
if (Bar.IsEditing) then
|
|
Bar.EndEdit(False);
|
|
if (Bar.FSelectedItem = Self) then
|
|
IsSelectedFlag := True;
|
|
if (Bar.FMouseFocusedItem = Self) then
|
|
Bar.FMouseFocusedItem := nil;
|
|
end;
|
|
if (Bar <> nil) and Assigned(Bar.FOnDeleteItem) then
|
|
Bar.FOnDeleteItem(Bar, Self);
|
|
inherited Destroy;
|
|
if (IsSelectedFlag) then
|
|
Bar.SetSelectedItem(nil);
|
|
if NeedRepaint then
|
|
Bar.InvalidateItems(True);
|
|
end;
|
|
|
|
procedure TdxSideBarItem.Assign(Source: TPersistent);
|
|
var
|
|
item: TdxSideBarItem;
|
|
begin
|
|
if (Source is TdxSideBarItem) then begin
|
|
item := TdxSideBarItem(Source);
|
|
FStoredItem := item.StoredItem;
|
|
FHint := item.Hint;
|
|
FIsDefault := item.IsDefault;
|
|
FCaption := item.Caption;
|
|
FTag := item.Tag;
|
|
FCustomData := item.CustomData;
|
|
FLargeImage := item.LargeImage;
|
|
FSmallImage := item.SmallImage;
|
|
FEnabled := item.Enabled;
|
|
end else inherited Assign(Source);
|
|
end;
|
|
|
|
function TdxSideBarItem.MakeVisible;
|
|
begin
|
|
Result := IsFullVisible and Group.Active;
|
|
if not Result and Group.Active then
|
|
Group.TopVisibleItem := SideBar.GetTopVisibleToMakeItemVisible(self);
|
|
end;
|
|
|
|
function TdxSideBarItem.IsSelected: Boolean;
|
|
begin
|
|
Result := SideBar.SelectedItem = self;
|
|
end;
|
|
|
|
function TdxSideBarItem.IsFocused: Boolean;
|
|
begin
|
|
Result := SideBar.FocusedItem = self;
|
|
end;
|
|
|
|
function TdxSideBarItem.IsFullVisible: Boolean;
|
|
begin
|
|
Result := (SideBar.ViewInfo.GetItemViewInfoByItem(self) <> nil)
|
|
and not SideBar.ViewInfo.GetItemViewInfoByItem(self).IsPartialVisible;
|
|
end;
|
|
|
|
function TdxSideBarItem.Visible: Boolean;
|
|
begin
|
|
Result := SideBar.ViewInfo.GetItemViewInfoByItem(self) <> nil;
|
|
end;
|
|
|
|
function TdxSideBarItem.GetCaption: string;
|
|
begin
|
|
if (FStoredItem <> nil) and IsDefault then
|
|
Result := FStoredItem.Caption
|
|
else Result := FCaption;
|
|
end;
|
|
|
|
function TdxSideBarItem.GetEnabled: Boolean;
|
|
begin
|
|
if (FStoredItem <> nil) and IsDefault then
|
|
Result := FStoredItem.Enabled
|
|
else Result := FEnabled;
|
|
end;
|
|
|
|
function TdxSideBarItem.GetHint: string;
|
|
begin
|
|
if (FStoredItem <> nil) and IsDefault then
|
|
Result := FStoredItem.Hint
|
|
else Result := FHint;
|
|
end;
|
|
|
|
function TdxSideBarItem.GetGroup: TdxSideGroup;
|
|
begin
|
|
if (Collection <> nil) then
|
|
Result := TdxSideBarItems(Collection).Group
|
|
else Result := nil;
|
|
end;
|
|
|
|
function TdxSideBarItem.GetSideBar: TdxSideBar;
|
|
begin
|
|
if Group <> nil then
|
|
Result := Group.SideBar
|
|
else Result := nil;
|
|
end;
|
|
|
|
function TdxSideBarItem.GetLargeImage: Integer;
|
|
begin
|
|
if (FStoredItem <> nil) and IsDefault then
|
|
Result := FStoredItem.LargeImage
|
|
else Result := FLargeImage;
|
|
end;
|
|
|
|
function TdxSideBarItem.GetSmallImage: Integer;
|
|
begin
|
|
if (FStoredItem <> nil) and IsDefault then
|
|
Result := FStoredItem.SmallImage
|
|
else Result := FSmallImage;
|
|
end;
|
|
|
|
procedure TdxSideBarItem.SetCaption(Value: string);
|
|
var
|
|
ABar: TdxSideBar;
|
|
begin
|
|
if (FCaption <> Value) then begin
|
|
FCaption := Value;
|
|
if (FStoredItem <> nil) and (FCaption <> FStoredItem.Caption) then
|
|
IsDefault := False;
|
|
if (Collection <> nil) then begin
|
|
ABar := TdxSideBarItems(Collection).SideBar;
|
|
if (ABar <> nil) and (ABar.ActiveGroup <> nil) and Visible then
|
|
ABar.InvalidateItems(True);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarItem.SetEnabled(Value: Boolean);
|
|
var
|
|
ABar: TdxSideBar;
|
|
begin
|
|
if (FEnabled <> Value) then
|
|
begin
|
|
FEnabled := Value;
|
|
if (FStoredItem <> nil) and (FEnabled <> FStoredItem.Enabled) then
|
|
IsDefault := False;
|
|
if (Collection <> nil) then begin
|
|
ABar := TdxSideBarItems(Collection).SideBar;
|
|
if (ABar <> nil) and (ABar.ActiveGroup <> nil) and Visible then
|
|
ABar.InvalidateItems(False);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarItem.SetHint(Value: string);
|
|
begin
|
|
if (FHint <> Value) then begin
|
|
FHint := Value;
|
|
if (FStoredItem <> nil) and (FHint <> FStoredItem.Hint) then
|
|
IsDefault := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarItem.SetIsDefault(Value: Boolean);
|
|
begin
|
|
FIsDefault := Value;
|
|
if (FStoredItem <> nil) and (Value) then begin
|
|
Caption := FStoredItem.Caption;
|
|
Hint := FStoredItem.Hint;
|
|
Enabled := FStoredItem.Enabled;
|
|
LargeImage := FStoredItem.LargeImage;
|
|
SmallImage := FStoredItem.SmallImage;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarItem.SetLargeImage(Value: Integer);
|
|
begin
|
|
if (FLargeImage <> Value) then begin
|
|
FLargeImage := Value;
|
|
if (FStoredItem <> nil) and (FLargeImage <> FStoredItem.LargeImage) then
|
|
IsDefault := False;
|
|
if (Collection <> nil) and
|
|
(TdxSideBarItems(Collection).SideBar.ActiveGroup =
|
|
TdxSideBarItems(Collection).Group) then
|
|
TdxSideBarItems(Collection).SideBar.InvalidateItems(False);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarItem.SetSmallImage(Value: Integer);
|
|
begin
|
|
if (FSmallImage <> Value) then begin
|
|
FSmallImage := Value;
|
|
if (FStoredItem <> nil) and (FSmallImage <> FStoredItem.SmallImage) then
|
|
IsDefault := False;
|
|
if (Collection <> nil) and
|
|
(TdxSideBarItems(Collection).SideBar.ActiveGroup =
|
|
TdxSideBarItems(Collection).Group) then
|
|
TdxSideBarItems(Collection).SideBar.InvalidateItems(False);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarItem.SetStoredItem(Value: TdxStoredSideItem);
|
|
begin
|
|
if (Value <> FStoredItem) then begin
|
|
FStoredItem := Value;
|
|
if (FStoredItem <> nil) and (Collection <> nil)
|
|
and not (csLoading in TdxSideBarItems(Collection).SideBar.ComponentState) then begin
|
|
FCaption := FStoredItem.Caption;
|
|
FSmallImage := FStoredItem.SmallImage;
|
|
FLargeImage := FStoredItem.LargeImage;
|
|
Tag := FStoredItem.Tag;
|
|
FIsDefault := True;
|
|
TdxSideBarItems(Collection).SideBar.RepaintAll;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{TdxSideBarStore}
|
|
constructor TdxSideBarStore.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FList := TList.Create;
|
|
FBars := TList.Create;
|
|
FCategories := TStoredSideBarItemsStoreStrings.Create(Self);
|
|
FLargeChangeLink := CreateChangeLink(OnChangeLink);
|
|
FSmallChangeLink := CreateChangeLink(OnChangeLink);
|
|
FDefaultLargeImage := -1;
|
|
FDefaultSmallImage := -1;
|
|
|
|
Designer := nil;
|
|
end;
|
|
|
|
destructor TdxSideBarStore.Destroy;
|
|
begin
|
|
FSmallChangeLink.Free;
|
|
FLargeChangeLink.Free;
|
|
if (Designer <> nil) then
|
|
Designer.Free;
|
|
DestroyItems;
|
|
FCategories.Free;
|
|
FBars.Free;
|
|
FList.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxSideBarStore.Notification(AComponent: TComponent;
|
|
Operation: TOperation);
|
|
begin
|
|
inherited Notification(AComponent, Operation);
|
|
if (Operation = opRemove) then begin
|
|
if (AComponent = LargeImages) then LargeImages := nil;
|
|
if (AComponent = SmallImages) then SmallImages := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarStore.DestroyItems;
|
|
var
|
|
Item: TdxStoredSideItem;
|
|
begin
|
|
while FList.Count > 0 do
|
|
begin
|
|
Item := TdxStoredSideItem(FList.Last);
|
|
RemoveItem(Item);
|
|
Item.Free;
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF DELPHI3}
|
|
procedure TdxSideBarStore.GetChildren(Proc: TGetChildProc; Root: TComponent);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
if Items[I].Owner = Root then Proc(Items[I]);
|
|
end;
|
|
{$ELSE}
|
|
procedure TdxSideBarStore.GetChildren(Proc: TGetChildProc);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
if Items[I].Owner <> Self then Proc(Items[I]);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TdxSideBarStore.SetName(const Value: TComponentName);
|
|
var
|
|
I: Integer;
|
|
OldName, ItemName, NamePrefix: TComponentName;
|
|
item: TdxStoredSideItem;
|
|
begin
|
|
OldName := Name;
|
|
inherited SetName(Value);
|
|
if (csDesigning in ComponentState) and (Name <> OldName) then
|
|
for I := 0 to Count - 1 do begin
|
|
item := Items[I];
|
|
if item.Owner = Owner then begin
|
|
itemName := item.Name;
|
|
NamePrefix := itemName;
|
|
if Length(NamePrefix) > Length(OldName) then begin
|
|
SetLength(NamePrefix, Length(OldName));
|
|
if CompareText(OldName, NamePrefix) = 0 then begin
|
|
Delete(itemName, 1, Length(OldName));
|
|
Insert(Value, itemName, 1);
|
|
try
|
|
item.Name := itemName;
|
|
except
|
|
on EComponentError do
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
if (Designer <> nil) then
|
|
Designer.SideBarStoreEditorUpdate;
|
|
end;
|
|
|
|
function TdxSideBarStore.GetCount: Integer;
|
|
begin
|
|
Result := FList.Count;
|
|
end;
|
|
|
|
function TdxSideBarStore.GetSideBarCount: Integer;
|
|
begin
|
|
Result := FBars.Count;
|
|
end;
|
|
|
|
function TdxSideBarStore.GetItem(Index: Integer): TdxStoredSideItem;
|
|
begin
|
|
if (Index > -1) and (Index < Count) then
|
|
Result := TdxStoredSideItem(FList[INdex])
|
|
else Result := nil;
|
|
end;
|
|
|
|
function TdxSideBarStore.GetSideBar(Index: Integer): TdxSideBar;
|
|
begin
|
|
Result := nil;
|
|
if (Index > -1) and (Index < FBars.Count) then
|
|
Result := TdxSideBar(FBars[Index]);
|
|
end;
|
|
|
|
procedure TdxSideBarStore.SetCategories(Value: TStrings);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if (Value.Count = 0) then begin
|
|
Categories.Clear;
|
|
Exit;
|
|
end;
|
|
if (Value.Count < FCategories.Count) then begin
|
|
for I := Value.Count to FCategories.Count - 1 do
|
|
if (GetCountByCategory(FCategories[I]) > 0) then begin
|
|
raise EdxSideBarError.Create(dxSideBarGetResourceString(@DXSB_CANTDELETEGROUP));
|
|
Exit;
|
|
end;
|
|
while Value.Count < Categories.Count do
|
|
FCategories.Delete(FCategories.Count - 1);
|
|
end else begin
|
|
for I := FCategories.Count to Value.Count - 1 do
|
|
FCategories.Add(Value[I]);
|
|
end;
|
|
for I := 0 to Value.Count - 1 do
|
|
FCategories[I]:= Value[I];
|
|
end;
|
|
|
|
procedure TdxSideBarStore.SetDefaultLargeImage(Value: Integer);
|
|
begin
|
|
if (Value >= -1) and (FDefaultLargeImage <> Value) then begin
|
|
FDefaultLargeImage := Value;
|
|
RedrawBars;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarStore.SetDefaultSmallImage(Value: Integer);
|
|
begin
|
|
if (Value >= -1) and (FDefaultSmallImage <> Value) then begin
|
|
FDefaultSmallImage := Value;
|
|
RedrawBars;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarStore.SetImages(AValue: TCustomImageList; var AImageList: TCustomImageList; AChangeLink: TChangeLink);
|
|
begin
|
|
if (AImageList <> AValue) then
|
|
begin
|
|
if (AImageList <> nil) and not (csDestroying in AImageList.ComponentState) then
|
|
AImageList.UnRegisterChanges(AChangeLink);
|
|
AImageList := AValue;
|
|
if (AImageList <> nil) then
|
|
begin
|
|
AImageList.RegisterChanges(AChangeLink);
|
|
AImageList.FreeNotification(Self);
|
|
end;
|
|
if not (csDestroying in ComponentState) then
|
|
begin
|
|
RedrawBars;
|
|
if (Designer <> nil) then
|
|
Designer.SideBarStoreEditorUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarStore.SetLargeImages(Value: TCustomImageList);
|
|
begin
|
|
SetImages(Value, FLargeImages, FLargeChangeLink);
|
|
end;
|
|
|
|
procedure TdxSideBarStore.SetSmallImages(Value: TCustomImageList);
|
|
begin
|
|
SetImages(Value, FSmallImages, FSmallChangeLink);
|
|
end;
|
|
|
|
function TdxSideBarStore.GetCountByCategory(St: string): Integer;
|
|
var
|
|
Index, I: Integer;
|
|
begin
|
|
Result := 0;
|
|
Index := FCategories.IndexOf(St);
|
|
if (Index > -1) then
|
|
for I := 0 to Count - 1 do
|
|
if (Items[I].Category = Index) then
|
|
Inc(Result);
|
|
end;
|
|
|
|
function TdxSideBarStore.GetItemByCategory(St: string; Index: Integer): TdxStoredSideItem;
|
|
var
|
|
List: TList;
|
|
begin
|
|
Result := nil;
|
|
List := TList.Create;
|
|
GetItemsByCategory(St, List);
|
|
if (Index < List.Count) then
|
|
Result := TdxStoredSideItem(List[Index]);
|
|
List.Free;
|
|
end;
|
|
|
|
function TdxSideBarStore.GetItemsByCategory(St: string; List: TList): Integer;
|
|
var
|
|
Index, I: Integer;
|
|
begin
|
|
List.Clear;
|
|
Index := FCategories.IndexOf(St);
|
|
if (Index > -1) then
|
|
for I := 0 to Count - 1 do
|
|
if (Items[I].Category = Index) then
|
|
List.Add(Items[I]);
|
|
Result := List.Count;
|
|
end;
|
|
|
|
procedure TdxSideBarStore.AddItem(Item: TdxStoredSideItem);
|
|
begin
|
|
FList.Add(Item);
|
|
end;
|
|
|
|
procedure TdxSideBarStore.ExchangeItems(Item1, Item2: TdxStoredSideItem);
|
|
var
|
|
Index1, Index2: Integer;
|
|
begin
|
|
Index1 := FList.IndexOf(Item1);
|
|
Index2 := FList.IndexOf(Item2);
|
|
if (Index1 > -1) and (Index2 > -1) then
|
|
FList.Exchange(Index1, Index2);
|
|
end;
|
|
|
|
procedure TdxSideBarStore.RemoveItem(Item: TdxStoredSideItem);
|
|
begin
|
|
RemoveBarItem(Item);
|
|
FList.Remove(Item);
|
|
end;
|
|
|
|
procedure TdxSideBarStore.OnChangeLink(Sender: TObject);
|
|
begin
|
|
RedrawBars;
|
|
end;
|
|
|
|
procedure TdxSideBarStore.RedrawBars;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to FBars.Count - 1 do
|
|
SideBars[I].RepaintAll;
|
|
end;
|
|
|
|
procedure TdxSideBarStore.RemoveBarItem(StoredItem: TdxStoredSideItem);
|
|
var
|
|
I, j, k: Integer;
|
|
begin
|
|
if (csDestroying in ComponentState) then Exit;
|
|
for I := 0 to FBars.Count - 1 do
|
|
if not (csDestroying in SideBars[I].ComponentState)
|
|
and (SideBars[I].Groups <> nil) then
|
|
for j := 0 to SideBars[I].Groups.Count - 1 do begin
|
|
k := 0;
|
|
while k < SideBars[I].Groups[j].Items.Count do begin
|
|
if (SideBars[I].Groups[j].Items[k].StoredItem = StoredItem) then
|
|
SideBars[I].Groups[j].Items[k].Free
|
|
else Inc(k);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarStore.UpdateItem(Item: TdxStoredSideItem);
|
|
begin
|
|
RedrawBars;
|
|
UpdateEditorItem(Item);
|
|
end;
|
|
|
|
procedure TdxSideBarStore.Customize;
|
|
begin
|
|
SideBarCustomize(Self);
|
|
end;
|
|
|
|
procedure TdxSideBarStore.UpdateEditorItem(Item: TdxStoredSideItem);
|
|
begin
|
|
if (Designer <> nil) then
|
|
Designer.SideBarStoreEditorUpdateItem(Item);
|
|
end;
|
|
|
|
{TdxStoredSideItem}
|
|
constructor TdxStoredSideItem.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FCaption := dxSideBarGetResourceString(@DXSB_DEFAULTITEMCAPTION);
|
|
FLargeImage := -1;
|
|
FSmallImage := -1;
|
|
FEnabled := True;
|
|
FAvailableInCustomizeForm := True;
|
|
end;
|
|
|
|
destructor TdxStoredSideItem.Destroy;
|
|
begin
|
|
if (FStore <> nil) then
|
|
FStore.RemoveItem(Self);
|
|
{$IFDEF DELPHI4}
|
|
if FActionLink <> nil then
|
|
begin
|
|
FActionLink.Free;
|
|
FActionLink := nil;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{$IFDEF DELPHI4}
|
|
procedure TdxStoredSideItem.Loaded;
|
|
begin
|
|
inherited;
|
|
if Action <> nil then ActionChange(Action, True);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TdxStoredSideItem.Notification(AComponent: TComponent; Operation: TOperation);
|
|
begin
|
|
inherited Notification(AComponent, Operation);
|
|
if (Operation = opRemove) and (AComponent = FPopupMenu) then FPopupMenu := nil;
|
|
if (Operation = opRemove) and (AComponent = FStore) then Store := nil;
|
|
{$IFDEF DELPHI4}
|
|
if (Operation = opRemove) and (AComponent = Action) then Action := nil;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function TdxStoredSideItem.GetParentComponent: TComponent;
|
|
begin
|
|
Result := FStore;
|
|
end;
|
|
|
|
function TdxStoredSideItem.HasParent: Boolean;
|
|
begin
|
|
HasParent := True;
|
|
end;
|
|
|
|
procedure TdxStoredSideItem.ReadState(Reader: TReader);
|
|
begin
|
|
inherited ReadState(Reader);
|
|
if Reader.Parent is TdxSideBarStore then Store := TdxSideBarStore(Reader.Parent);
|
|
end;
|
|
|
|
procedure TdxStoredSideItem.SetParentComponent(AParent: TComponent);
|
|
begin
|
|
if not (csLoading in ComponentState) then Store := AParent as TdxSideBarStore;
|
|
end;
|
|
|
|
{$IFDEF DELPHI4}
|
|
procedure TdxStoredSideItem.ActionChange(Sender: TObject; CheckDefaults: Boolean);
|
|
begin
|
|
if Action is TCustomAction then
|
|
with TCustomAction(Sender) do
|
|
begin
|
|
if not CheckDefaults or (Self.Caption = '') or (Self.Caption = dxSideBarGetResourceString(@DXSB_DEFAULTITEMCAPTION)) then
|
|
Self.Caption := Caption;
|
|
if not CheckDefaults or (Self.Enabled = True) then
|
|
Self.Enabled := Enabled;
|
|
if not CheckDefaults or (Self.Hint = '') then
|
|
Self.Hint := Hint;
|
|
if not CheckDefaults or (Self.LargeImage = -1) then
|
|
Self.LargeImage := ImageIndex;
|
|
end;
|
|
end;
|
|
|
|
function TdxStoredSideItem.GetActionLinkClass: TdxSideBarItemActionLinkClass;
|
|
begin
|
|
Result := TdxSideBarItemActionLink;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF DELPHI4}
|
|
function TdxStoredSideItem.GetAction: TBasicAction;
|
|
begin
|
|
if FActionLink = nil then Result := nil
|
|
else Result := FActionLink.Action;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF DELPHI4}
|
|
procedure TdxStoredSideItem.SetAction(Value: TBasicAction);
|
|
begin
|
|
if Value = nil then
|
|
begin
|
|
if FActionLink <> nil then
|
|
FActionLink.Free;
|
|
FActionLink := nil;
|
|
end
|
|
else
|
|
begin
|
|
if (Value is TCustomAction) and (csDesigning in Value.ComponentState) then
|
|
TCustomAction(Value).DisableIfNoHandler := False;
|
|
if FActionLink = nil then
|
|
FActionLink := GetActionLinkClass.Create(Self);
|
|
FActionLink.Action := Value;
|
|
FActionLink.OnChange := DoActionChange;
|
|
ActionChange(Value, csLoading in Value.ComponentState);
|
|
Value.FreeNotification(Self);
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TdxStoredSideItem.SetCaption(Value: string);
|
|
begin
|
|
if (FCaption <> Value) then begin
|
|
FCaption := Value;
|
|
if (FStore <> nil) then
|
|
FStore.UpdateItem(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxStoredSideItem.SetEnabled(Value: Boolean);
|
|
begin
|
|
if (FEnabled <> Value) then begin
|
|
FEnabled := Value;
|
|
if (FStore <> nil) then
|
|
FStore.UpdateItem(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxStoredSideItem.SetHint(Value: string);
|
|
begin
|
|
if (FHint <> Value) then begin
|
|
FHint := Value;
|
|
if (FStore <> nil) then
|
|
FStore.UpdateItem(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxStoredSideItem.DoClick(Sender: TObject; Item: TdxSideBarItem);
|
|
begin
|
|
if Assigned(FOnClick) then
|
|
FOnClick(Sender, Item)
|
|
else
|
|
if FActionLink <> nil then
|
|
FActionLink.Execute;
|
|
end;
|
|
|
|
procedure TdxStoredSideItem.SetCategory(Value: Integer);
|
|
begin
|
|
if (csLoading in ComponentState) then
|
|
FCategory := Value
|
|
else
|
|
if (FStore <> nil) and (Value > - 1)
|
|
and (Value < FStore.Categories.Count) then begin
|
|
FCategory := Value;
|
|
FStore.UpdateEditorItem(Self)
|
|
end;
|
|
end;
|
|
|
|
procedure TdxStoredSideItem.SetLargeImage(Value: Integer);
|
|
begin
|
|
if (FLargeImage <> Value) then begin
|
|
FLargeImage := Value;
|
|
if (FStore <> nil) then
|
|
FStore.UpdateItem(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxStoredSideItem.SetSmallImage(Value: Integer);
|
|
begin
|
|
if (FSmallImage <> Value) then begin
|
|
FSmallImage := Value;
|
|
if (FStore <> nil) then
|
|
FStore.UpdateItem(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxStoredSideItem.SetStore(Value: TdxSideBarStore);
|
|
begin
|
|
if (FStore <> Value) then begin
|
|
if (FStore <> nil) then
|
|
FStore.RemoveItem(Self);
|
|
FStore := Value;
|
|
if (FStore <> nil) then begin
|
|
FStore.AddItem(Self);
|
|
if not (csLoading in ComponentState) then
|
|
Category := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF DELPHI4}
|
|
procedure TdxStoredSideItem.DoActionChange(Sender: TObject);
|
|
begin
|
|
if Sender = Action then ActionChange(Sender, False);
|
|
end;
|
|
|
|
function TdxStoredSideItem.IsCaptionStored: Boolean;
|
|
begin
|
|
Result := (FActionLink = nil) or not FActionLink.IsCaptionLinked;
|
|
end;
|
|
|
|
function TdxStoredSideItem.IsEnabledStored: Boolean;
|
|
begin
|
|
Result := (FActionLink = nil) or not FActionLink.IsEnabledLinked;
|
|
end;
|
|
|
|
function TdxStoredSideItem.IsHintStored: Boolean;
|
|
begin
|
|
Result := (FActionLink = nil) or not FActionLink.IsHintLinked;
|
|
end;
|
|
|
|
function TdxStoredSideItem.IsImageIndexStored: Boolean;
|
|
begin
|
|
Result := (FActionLink = nil) or not FActionLink.IsImageIndexLinked;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TdxSideBarStoreCustomizeForm.BeginCustomizing;
|
|
begin
|
|
Store.FIsCustomizing := True;
|
|
end;
|
|
|
|
procedure TdxSideBarStoreCustomizeForm.EndCustomizing;
|
|
begin
|
|
Store.FIsCustomizing := False;
|
|
end;
|
|
|
|
{TdxSideItemW2KViewInfo}
|
|
|
|
function TdxSideItemW2KViewInfo.GetBorderRect: TRect;
|
|
begin
|
|
Result := inherited GetBorderRect;
|
|
Result.Left := ViewInfo.ItemsRect.Left;
|
|
Result.Right := ViewInfo.ItemsRect.Right;
|
|
if Result.Bottom < CaptionRect.Bottom then
|
|
Result.Bottom := CaptionRect.Bottom;
|
|
Dec(Result.Top, Painter.SideBar.SpaceHeight);
|
|
Inc(Result.Bottom, Painter.SideBar.SpaceHeight - 1);
|
|
end;
|
|
|
|
{TdxSideBarW2KViewInfo}
|
|
function TdxSideBarW2KViewInfo.GetSideBarTopItemSpaceHeight: Integer;
|
|
begin
|
|
Result := 2;
|
|
end;
|
|
|
|
function TdxSideBarW2KViewInfo.CreateItemInfo(AItem: TdxSideBarItem; AImageRect, ACaptionRect: TRect): TdxSideItemViewInfo;
|
|
begin
|
|
Result := TdxSideItemW2KViewInfo.Create(self, AItem, AImageRect, ACaptionRect);
|
|
end;
|
|
|
|
{TdxSideBarW2KPainter}
|
|
function TdxSideBarW2KPainter.CreateViewInfo: TdxSideBarViewInfo;
|
|
begin
|
|
Result := TdxSideBarW2KViewInfo.Create(self);
|
|
end;
|
|
|
|
{ TdxSideBarPopupMenu }
|
|
constructor TdxSideBarPopupMenu.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
Bar := nil;
|
|
List := TList.Create;
|
|
FOptions := [sbmIconType, sbmAddGroup, sbmRemoveGroup, sbmCustomize,
|
|
sbmRenameGroup, sbmRenameItem, sbmRemoveItem];
|
|
end;
|
|
|
|
destructor TdxSideBarPopupMenu.Destroy;
|
|
begin
|
|
DestroyBarItems;
|
|
List.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxSideBarPopupMenu.Popup(X, Y: Integer);
|
|
var
|
|
MenuItem: TMenuItem;
|
|
const
|
|
Flags: array[TPopupAlignment] of Word = (TPM_LEFTALIGN, TPM_RIGHTALIGN,
|
|
TPM_CENTERALIGN);
|
|
|
|
procedure InsertNewMenuItem(const ACaption: string; AEnabled, AChecked: Boolean; ATag: TdxSideBarTag);
|
|
begin
|
|
MenuItem := NewItem(ACaption, 0, AChecked, AEnabled, BarMenuClick, 0, '');
|
|
MenuItem.Tag := ATag;
|
|
Items.Insert(List.Count, MenuItem);
|
|
List.Add(MenuItem);
|
|
end;
|
|
|
|
begin
|
|
if (List.Count > 0) then
|
|
DestroyBarItems;
|
|
Bar := nil;
|
|
if (PopupComponent <> nil) and (PopupComponent is TdxSideBar) then
|
|
begin
|
|
Bar := PopupComponent As TdxSideBar;
|
|
Group := Bar.GetPopupGroup;
|
|
FocusedItem := Bar.FocusedItem;
|
|
|
|
if FocusedItem = nil then
|
|
begin
|
|
if (sbmIconType in FOptions) and (Group <> nil) then begin
|
|
InsertNewMenuItem(dxSideBarGetResourceString(@DXSB_LARGEICONTYPE), True, Group.IconType = dxsgLargeIcon, -101);
|
|
InsertNewMenuItem(dxSideBarGetResourceString(@DXSB_SMALLICONTYPE), True, Group.IconType = dxsgSmallIcon, -102);
|
|
end;
|
|
if (sbmAddGroup in FOptions) or (sbmRemoveGroup in FOptions)
|
|
or (sbmRenameGroup in FOptions) then begin
|
|
if (List.Count > 0) then
|
|
InsertNewMenuItem('-', True, False, 0);
|
|
if (sbmAddGroup in FOptions) then
|
|
InsertNewMenuItem(dxSideBarGetResourceString(@DXSB_ADDGROUP), True, False, -201);
|
|
if (sbmRemoveGroup in FOptions) then
|
|
InsertNewMenuItem(dxSideBarGetResourceString(@DXSB_REMOVEGROUP), Group <> nil, False, -202);
|
|
if (sbmRenameGroup in FOptions) then
|
|
InsertNewMenuItem(dxSideBarGetResourceString(@DXSB_RENAMEGROUP), Group <> nil, False, -203);
|
|
end;
|
|
if (sbmCustomize in FOptions) and (Bar <> nil) and (Bar.Store <> nil)
|
|
and (Group <> nil) then begin
|
|
if (List.Count > 0) and (TMenuItem(List.Last).Caption <> '-') then
|
|
InsertNewMenuItem('-', True, False, 0);
|
|
InsertNewMenuItem(dxSideBarGetResourceString(@DXSB_CUSTOMIZE), True, False, -401);
|
|
end;
|
|
end else begin
|
|
if (sbmRemoveItem in FOptions) then
|
|
InsertNewMenuItem(dxSideBarGetResourceString(@DXSB_REMOVEITEM), True, False, -301);
|
|
if (sbmRenameItem in FOptions) then
|
|
InsertNewMenuItem(dxSideBarGetResourceString(@DXSB_RENAMEITEM), True, False, -302);
|
|
end;
|
|
if (Items.Count > List.Count) and (List.Count > 0)
|
|
and (TMenuItem(List.Last).Caption <> '-') then
|
|
InsertNewMenuItem('-', True, False, 0);
|
|
end;
|
|
inherited Popup(X, Y);
|
|
CallNotify(FOnPopupClose, Self);
|
|
end;
|
|
|
|
procedure TdxSideBarPopupMenu.BarMenuClick(Sender: TObject);
|
|
var
|
|
tag: LongInt;
|
|
gr: TdxSideGroup;
|
|
begin
|
|
if not (Sender is TMenuItem) then Exit;
|
|
tag := TMenuItem(Sender).Tag;
|
|
case tag of
|
|
-101: Group.IconType := dxsgLargeIcon;
|
|
-102: Group.IconType := dxsgSmallIcon;
|
|
-201:
|
|
begin
|
|
gr := Bar.Groups.Add;
|
|
Bar.EditGroup(gr);
|
|
end;
|
|
-202: Group.Free;
|
|
-203: Bar.EditGroup(Group);
|
|
-301:
|
|
begin
|
|
Bar.FMouseFocusedItem := nil;
|
|
FocusedItem.Free;
|
|
end;
|
|
-302: Bar.EditItem(FocusedItem);
|
|
-401: if (Bar.Store <> nil) then Bar.Store.Customize;
|
|
end;
|
|
CallNotify(FOnAfterClick, Self);
|
|
end;
|
|
|
|
procedure TdxSideBarPopupMenu.DestroyBarItems;
|
|
var
|
|
MenuItem: TMenuItem;
|
|
begin
|
|
if (Bar <> nil) then
|
|
begin
|
|
while List.Count > 0 do begin
|
|
MenuItem := TMenuItem(List[0]);
|
|
List.Remove(MenuItem);
|
|
MenuItem.Free;
|
|
end;
|
|
Bar := nil;
|
|
end;
|
|
end;
|
|
|
|
{TdxSideItemViewInfo}
|
|
constructor TdxSideItemViewInfo.Create(AViewInfo: TdxSideBarViewInfo; AItem: TdxSideBarItem; AImageRect, ACaptionRect: TRect);
|
|
begin
|
|
inherited Create;
|
|
FViewInfo := AViewInfo;
|
|
FItem := AItem;
|
|
FImageRect := AImageRect;
|
|
FCaptionRect := ACaptionRect;
|
|
end;
|
|
|
|
function TdxSideItemViewInfo.GetPainter: TdxSideBarPainter;
|
|
begin
|
|
Result := ViewInfo.Painter;
|
|
end;
|
|
|
|
function TdxSideItemViewInfo.Index: Integer;
|
|
begin
|
|
Result := ViewInfo.ItemIndexOf(self);
|
|
end;
|
|
|
|
function TdxSideItemViewInfo.IsPartialVisible: Boolean;
|
|
begin
|
|
Result := Bottom > ViewInfo.ItemsRect.Bottom;
|
|
end;
|
|
|
|
function TdxSideItemViewInfo.Bottom: Integer;
|
|
begin
|
|
Result := ItemRect.Bottom;
|
|
end;
|
|
|
|
function TdxSideItemViewInfo.Top: Integer;
|
|
begin
|
|
Result := ItemRect.Top;
|
|
end;
|
|
|
|
function TdxSideItemViewInfo.FocusedCaptionRect: TRect;
|
|
begin
|
|
Result := CaptionRect;
|
|
if (Item.Group.IconType = dxsgLargeIcon) then
|
|
Result.Top := ImageRect.Bottom
|
|
else Result.Left := ImageRect.Right;
|
|
end;
|
|
|
|
function TdxSideItemViewInfo.GetItemDragSourceSpace(APosition: TdxSideBarDragSourcePosition): TRect;
|
|
begin
|
|
Result := ViewInfo.ItemsRect;
|
|
case APosition of
|
|
sbdspTop:
|
|
begin
|
|
Result.Bottom := Top;
|
|
Result.Top := Result.Bottom - dxSideBarDragArrowHeight + 1;
|
|
end;
|
|
sbdspBottom:
|
|
begin
|
|
Result.Top := Bottom;
|
|
Result.Bottom := Result.Top + dxSideBarDragArrowHeight - 1;
|
|
end;
|
|
sbdspIn:
|
|
begin
|
|
Result.Top := Top;
|
|
Result.Bottom := Bottom;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxSideItemViewInfo.GetBorderRect: TRect;
|
|
begin
|
|
Result := ImageRect;
|
|
InflateRect(Result, ViewInfo.GetBorderOffSet, ViewInfo.GetBorderOffSet);
|
|
end;
|
|
|
|
function TdxSideItemViewInfo.GetItemRect: TRect;
|
|
begin
|
|
Result.Left := Min(Min(CaptionRect.Left, ImageRect.Left), BorderRect.Left);
|
|
Result.Top := Min(Min(CaptionRect.Top, ImageRect.Top), BorderRect.Top);
|
|
Result.Right := Max(Max(CaptionRect.Right, ImageRect.Right), BorderRect.Right);
|
|
Result.Bottom := Max(Max(CaptionRect.Bottom, ImageRect.Bottom), BorderRect.Bottom);
|
|
end;
|
|
|
|
function TdxSideItemViewInfo.GetCaption: String;
|
|
begin
|
|
Result := Item.Caption;
|
|
end;
|
|
|
|
function TdxSideItemViewInfo.GetImageIndex: Integer;
|
|
begin
|
|
if Item.Group.IconType = dxsgLargeIcon then
|
|
Result := Item.LargeImage
|
|
else Result := Item.SmallImage;
|
|
end;
|
|
|
|
function TdxSideItemViewInfo.GetImageList: TCustomImageList;
|
|
begin
|
|
if Item.Group.IconType = dxsgLargeIcon then
|
|
Result := Painter.SideBar.GetLargeImages
|
|
else
|
|
Result := Painter.SideBar.GetSmallImages;
|
|
end;
|
|
|
|
{TdxSideBarItems}
|
|
constructor TdxSideBarItems.Create(AOwner: TdxSideGroup);
|
|
begin
|
|
inherited Create(TdxSideBarItem);
|
|
Group := AOwner;
|
|
SideBar := TdxSideGroups(Group.Collection).SideBar;
|
|
end;
|
|
|
|
procedure TdxSideBarItems.Update(Item: TCollectionItem);
|
|
begin
|
|
if (SideBar <> nil) and (SideBar.Owner <> nil)
|
|
and not (csLoading in SideBar.Owner.ComponentState)
|
|
and (SideBar.ActiveGroup = Group) then
|
|
SideBar.InvalidateItems(True);
|
|
end;
|
|
|
|
function TdxSideBarItems.Add: TdxSideBarItem;
|
|
begin
|
|
Result := TdxSideBarItem(inherited Add);
|
|
end;
|
|
|
|
function TdxSideBarItems.GetItem(Index: Integer): TdxSideBarItem;
|
|
begin
|
|
Result := TdxSideBarItem(inherited Items[Index]);
|
|
end;
|
|
|
|
procedure TdxSideBarItems.SetItem(Index: Integer; Value: TdxSideBarItem);
|
|
begin
|
|
Items[Index].Assign(Value);
|
|
end;
|
|
|
|
{TdxSideBarXPViewInfo}
|
|
function TdxSideBarXPViewInfo.GetGroupHeight: Integer;
|
|
begin
|
|
Result := SideBar.GroupHeightOffSet * 2;
|
|
if (Result = 0) then
|
|
Result := 8;
|
|
Inc(Result, GetFontHeight(SideBar.GroupFont));
|
|
end;
|
|
|
|
function TdxSideBarXPViewInfo.GetPaintRect: TRect;
|
|
begin
|
|
if SideBar.ShowGroups then
|
|
SetRect(Result, 1, 1, SideBar.ClientWidth - 1, SideBar.ClientHeight - 1)
|
|
else SetRect(Result, 1, 0, SideBar.ClientWidth - 1, SideBar.ClientHeight);
|
|
end;
|
|
|
|
function TdxSideBarXPViewInfo.GetGroupOffSet: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxSideBarXPViewInfo.GetBorderOffSet: Integer;
|
|
begin
|
|
Result := 5;
|
|
end;
|
|
|
|
{TdxSideBarXPPainter}
|
|
function TdxSideBarXPPainter.CreateViewInfo: TdxSideBarViewInfo;
|
|
begin
|
|
Result := TdxSideBarXPViewInfo.Create(Self);
|
|
end;
|
|
|
|
procedure TdxSideBarXPPainter.DoDrawItemBorder(AItemViewInfo: TdxSideItemViewInfo; const ARect: TRect);
|
|
var
|
|
OldColor: TColor;
|
|
begin
|
|
DrawImageBackground(AItemViewInfo, ARect);
|
|
OldColor := Canvas.Brush.Color;
|
|
Canvas.Brush.Color := clHighlight;
|
|
Canvas.FrameRect(ARect);
|
|
Canvas.Brush.Color := OldColor;
|
|
ExcludeClipRect(ARect);
|
|
end;
|
|
|
|
procedure TdxSideBarXPPainter.InvalidateItemBorder(AItem: TdxSideBarItem);
|
|
var
|
|
AItemViewInfo: TdxSideItemViewInfo;
|
|
begin
|
|
AItemViewInfo := ViewInfo.GetItemViewInfoByItem(AItem);
|
|
if AItemViewInfo <> nil then
|
|
cxInvalidateRect(SideBar.Handle, AItemViewInfo.BorderRect, True);
|
|
end;
|
|
|
|
procedure TdxSideBarXPPainter.DrawBorder;
|
|
var
|
|
r: TRect;
|
|
begin
|
|
SetRect(r, 0, 0, ClientWidth, ClientHeight);
|
|
DrawEdge(DC, r, BDR_SUNKENOUTER, BF_RECT);
|
|
InflateRect(r, -1, -1);
|
|
IntersectClipRect(r);
|
|
end;
|
|
|
|
procedure TdxSideBarXPPainter.DrawGroup(AGroupViewInfo: TdxSideGroupViewInfo);
|
|
var
|
|
r, r1: TRect;
|
|
begin
|
|
Canvas.Brush.Color := clBtnFace;
|
|
Canvas.Font := SideBar.GroupFont;
|
|
r := AGroupViewInfo.Rect;
|
|
|
|
InflateRect(r, -1, -1);
|
|
r1 := r;
|
|
cxDrawText(DC, AGroupViewInfo.Caption, r1,
|
|
DT_CENTER or DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS or DT_NOPREFIX);
|
|
cxDrawText(DC, AGroupViewInfo.Caption, r1,
|
|
DT_CENTER or DT_VCENTER or DT_CALCRECT or DT_END_ELLIPSIS or DT_NOPREFIX);
|
|
if (r1.Right > r.Right) then
|
|
begin
|
|
r1.Left := r.Left;
|
|
r1.Right := r.Right;
|
|
end;
|
|
|
|
OffSetRect(r1, ((r.Right - r.Left) - (r1.Right - r1.Left)) div 2,
|
|
((r.Bottom - r.Top) - (r1.Bottom - r1.Top)) div 2);
|
|
ExcludeClipRect(r1);
|
|
Canvas.FillRect(r);
|
|
|
|
InflateRect(r, 1, 1);
|
|
if (SideBar.FMouseFocusedGroup = AGroupViewInfo.Group) then
|
|
begin
|
|
if not SideBar.FMouseFocusedGroupIsDown then
|
|
begin
|
|
DrawEdge(DC, r, BDR_RAISEDINNER, BF_TOPLEFT);
|
|
DrawEdge(DC, r, BDR_RAISEDOUTER, BF_BOTTOMRIGHT);
|
|
InflateRect(r, -1, -1);
|
|
DrawEdge(DC, r, BDR_RAISEDINNER, BF_BOTTOMRIGHT);
|
|
Dec(r.Bottom);
|
|
Dec(r.Right);
|
|
end
|
|
else
|
|
begin
|
|
DrawEdge(DC, r, BDR_SUNKENINNER, BF_TOPLEFT);
|
|
DrawEdge(DC, r, BDR_SUNKENOUTER, BF_BOTTOMRIGHT);
|
|
InflateRect(r, -1, -1);
|
|
DrawEdge(DC, r, BDR_SUNKENOUTER, BF_TOPLEFT);
|
|
Inc(r.Top);
|
|
Inc(r.Left);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
DrawEdge(DC, r, BDR_RAISEDINNER, BF_TOPLEFT);
|
|
DrawEdge(DC, r, BDR_RAISEDINNER, BF_BOTTOMRIGHT);
|
|
end;
|
|
ExcludeClipRect(AGroupViewInfo.Rect);
|
|
end;
|
|
|
|
procedure TdxSideBarXPPainter.DrawImageBackground(AItemViewInfo: TdxSideItemViewInfo; ARect: TRect);
|
|
var
|
|
brush: HBrush;
|
|
begin
|
|
if (AItemViewInfo.Item.IsSelected)or (AItemViewInfo.Item.IsFocused)then
|
|
begin
|
|
brush := CreateSolidBrush(TdxSideBar.XPSelectedItemColor);
|
|
Windows.FillRect(DC, ARect, brush);
|
|
DeleteObject(brush);
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
function TdxSideBarXPPainter.IsGroupFocused: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
{TdxSideBar}
|
|
constructor TdxSideBar.Create(AOwner: TComponent);
|
|
|
|
function CreateTimer(AInterval: Integer; AOnTimer: TNotifyEvent): TTimer;
|
|
begin
|
|
Result := TTimer.Create(nil);
|
|
Result.Enabled := False;
|
|
Result.Interval := AInterval;
|
|
Result.OnTimer := AOnTimer;
|
|
end;
|
|
|
|
begin
|
|
inherited Create(AOwner);
|
|
|
|
PaintStyle := sbpsFlat;
|
|
|
|
FScrollTimer := CreateTimer(300, DoScrollTimer);
|
|
FHintTimer := CreateTimer(dxSideBarHintShowDelay, DoHintTimer);
|
|
|
|
ControlStyle := ControlStyle - [csSetCaption, csAcceptsControls];
|
|
FGroups := TdxSideGroups.Create(Self);
|
|
FGroupFont := TFont.Create;
|
|
FGroupFont.OnChange := OnFontChange;
|
|
FItemFont := TFont.Create;
|
|
FImageList := TImageList.Create(Self);
|
|
FItemFont.Color := clWindow;
|
|
FItemFont.OnChange := OnFontChange;
|
|
FBkPicture := TPicture.Create;
|
|
FBkPicture.OnChange := DoBkPictureChange;
|
|
Color := clGrayText;
|
|
FBkGround := TdxSideBarBackGround.Create;
|
|
FBkGround.OnChange := DoBkPictureChange;
|
|
|
|
FSpaceHeight := 7;
|
|
BevelInner := bvNone;
|
|
BevelOuter := bvNone;
|
|
|
|
FLargeChangeLink := CreateChangeLink(OnChangeLink);
|
|
FSmallChangeLink := CreateChangeLink(OnChangeLink);
|
|
|
|
Align := alLeft;
|
|
Height := 300;
|
|
Width := 150;
|
|
FDropItemPosition := sbdspIn;
|
|
|
|
FShowGroups := True;
|
|
end;
|
|
|
|
destructor TdxSideBar.Destroy;
|
|
begin
|
|
FreeAndNil(FScrollTimer);
|
|
FreeAndNil(FHintTimer);
|
|
|
|
if StoreInRegistry and not (csDesigning in ComponentState) and (RegistryPath <> '') then
|
|
SaveToRegistry(RegistryPath);
|
|
|
|
FDestroying := True;
|
|
FLargeChangeLink.Free;
|
|
FSmallChangeLink.Free;
|
|
|
|
Store := nil;
|
|
FreeAndNil(FHintWindow);
|
|
FImageList.Free;
|
|
FGroupFont.Free;
|
|
FItemFont.Free;
|
|
FGroups.Free;
|
|
FBkPicture.Free;
|
|
FBkGround.Free;
|
|
|
|
FreeAndNil(FPainter);
|
|
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxSideBar.Loaded;
|
|
begin
|
|
inherited Loaded;
|
|
{load from registry}
|
|
if StoreInregistry and not (csDesigning in ComponentState) and (RegistryPath <> '') then
|
|
LoadFromRegistry(RegistryPath);
|
|
if (ActiveGroup = nil) then
|
|
ActiveGroupIndex := 0;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
|
|
begin
|
|
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
|
|
Painter.NeedRecalViewInfo;
|
|
end;
|
|
|
|
function GetRealColor(AColor: COLORREF): COLORREF;
|
|
var
|
|
DC: HDC;
|
|
begin
|
|
DC := GetDC(0);
|
|
Result := GetNearestColor(DC, AColor);
|
|
ReleaseDC(0, DC);
|
|
end;
|
|
|
|
function GetLightColor(ABtnFaceColorPart, AHighlightColorPart, AWindowColorPart: Integer): COLORREF;
|
|
var
|
|
ABtnFaceColor, AHighlightColor, AWindowColor: COLORREF;
|
|
|
|
function GetLightIndex(ABtnFaceValue, AHighlightValue, AWindowValue: Byte): Integer;
|
|
begin
|
|
Result :=
|
|
MulDiv(ABtnFaceValue, ABtnFaceColorPart, 100) +
|
|
MulDiv(AHighlightValue, AHighlightColorPart, 100) +
|
|
MulDiv(AWindowValue, AWindowColorPart, 100);
|
|
if Result < 0 then Result := 0;
|
|
if Result > 255 then Result := 255;
|
|
end;
|
|
|
|
begin
|
|
ABtnFaceColor := GetSysColor(COLOR_BTNFACE);
|
|
AHighlightColor := GetSysColor(COLOR_HIGHLIGHT);
|
|
AWindowColor := GetSysColor(COLOR_WINDOW);
|
|
if (ABtnFaceColor = 0) or (ABtnFaceColor = $FFFFFF) then
|
|
Result := AHighlightColor
|
|
else
|
|
Result := RGB(
|
|
GetLightIndex(GetRValue(ABtnFaceColor), GetRValue(AHighlightColor), GetRValue(AWindowColor)),
|
|
GetLightIndex(GetGValue(ABtnFaceColor), GetGValue(AHighlightColor), GetGValue(AWindowColor)),
|
|
GetLightIndex(GetBValue(ABtnFaceColor), GetBValue(AHighlightColor), GetBValue(AWindowColor)));
|
|
end;
|
|
|
|
class function TdxSideBar.XPBackgroundColor: COLORREF;
|
|
|
|
function GetLightValue(Value: Byte): Byte;
|
|
begin
|
|
Result := Value + MulDiv(255 - Value, 16, 100);
|
|
end;
|
|
|
|
begin
|
|
Result := GetSysColor(COLOR_BTNFACE);
|
|
Result := RGB(
|
|
GetLightValue(GetRValue(Result)),
|
|
GetLightValue(GetGValue(Result)),
|
|
GetLightValue(GetBValue(Result)));
|
|
Result := GetRealColor(Result);
|
|
end;
|
|
|
|
class function TdxSideBar.XPSelectedItemColor: COLORREF;
|
|
begin
|
|
Result := GetRealColor(GetLightColor(-2, 30, 72));
|
|
end;
|
|
|
|
procedure TdxSideBar.Notification(AComponent: TComponent; Operation: TOperation);
|
|
begin
|
|
inherited Notification(AComponent, Operation);
|
|
if (Operation = opRemove) then begin
|
|
if (AComponent = FGroupPopupMenu) then FGroupPopupMenu := nil;
|
|
if (AComponent = FItemPopupMenu) then FItemPopupMenu := nil;
|
|
if (AComponent = FStore) then Store := nil;
|
|
if (AComponent = LargeImages) then LargeImages := nil;
|
|
if (AComponent = SmallImages) then SmallImages := nil;
|
|
end
|
|
end;
|
|
|
|
procedure TdxSideBar.Assign(Source: TPersistent);
|
|
begin
|
|
if (Source is TdxSideBar) then begin
|
|
FAssignFlag := True;
|
|
FMouseFocusedGroup := nil;
|
|
Store := TdxSideBar(Source).Store;
|
|
SetGroups(TdxSideBar(Source).Groups);
|
|
SmallImages := TdxSideBar(Source).SmallImages;
|
|
LargeImages := TdxSideBar(Source).LargeImages;
|
|
FAssignFlag := False;
|
|
RepaintAll;
|
|
end;
|
|
end;
|
|
|
|
function TdxSideBar.GetGroupCount: Integer;
|
|
begin
|
|
Result := FGroups.Count;
|
|
end;
|
|
|
|
function TdxSideBar.GetHintWindow: THintWindow;
|
|
begin
|
|
if(FHintWindow = nil) then
|
|
FHintWindow := THintWindow.Create(nil);
|
|
Result := FHintWindow;
|
|
end;
|
|
|
|
function TdxSideBar.GetPainter: TdxSideBarPainter;
|
|
begin
|
|
if FPainter = nil then
|
|
FPainter := CreatePainter;
|
|
Result := FPainter;
|
|
end;
|
|
|
|
function TdxSideBar.GetScrollDelay: Integer;
|
|
begin
|
|
if FScrollTimer <> nil then
|
|
Result := FScrollTimer.Interval
|
|
else Result := 300;
|
|
end;
|
|
|
|
function TdxSideBar.GetViewInfo: TdxSideBarViewInfo;
|
|
begin
|
|
Result := Painter.ViewInfo;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetActiveGroup(Value: TdxSideGroup);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if (Store <> nil) and not (csDesigning in Store.ComponentState) then
|
|
for I := 0 to Store.Count - 1 do
|
|
with Store.Items[I] do
|
|
if FActionLink <> nil then FActionLink.Update;
|
|
|
|
if (Value <> nil) and not Value.Visible then
|
|
Value := nil;
|
|
|
|
if (FActiveGroup <> Value) or ((FActiveGroup <> nil) and (not FActiveGroup.Visible))
|
|
and not (csDestroying in ComponentState) then
|
|
begin
|
|
DoItemMouseFocused(nil, False);
|
|
|
|
SetMouseFocusedItem(nil);
|
|
FMouseFocusedItemIsDown := False;
|
|
SetDestDropItemandPosition(nil, sbdspIn);
|
|
FOldActiveGroup := FActiveGroup;
|
|
if (Value = nil) and (VisibleGroupCount > 0) then
|
|
FActiveGroup := VisibleGroups[0]
|
|
else
|
|
FActiveGroup := Value;
|
|
if FActiveGroup <> nil then
|
|
begin
|
|
ActiveGroupIndex := GetVisibleIndexByGroup(FActiveGroup);
|
|
FActiveGroup.FTopVisibleItem := 0;
|
|
end
|
|
else
|
|
ActiveGroupIndex := -1;
|
|
CallNotify(FOnChangeActiveGroup, Self);
|
|
RepaintAll;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetActiveGroupIndex(Value: Integer);
|
|
begin
|
|
if (FActiveGroupIndex <> Value) then
|
|
begin
|
|
if ((Value < 0) or (Value >= VisibleGroupCount)) and (VisibleGroupCount > 0) then
|
|
FActiveGroupIndex := 0
|
|
else
|
|
FActiveGroupIndex := Value;
|
|
end;
|
|
if (VisibleGroupCount > 0) and (FActiveGroupIndex < VisibleGroupCount) then
|
|
ActiveGroup := VisibleGroups[FActiveGroupIndex];
|
|
end;
|
|
|
|
procedure TdxSideBar.SetBkGround(Value: TdxSideBarBackGround);
|
|
begin
|
|
FBkGround := Value;
|
|
RepaintAll;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetBkPicture(Value: TPicture);
|
|
begin
|
|
FBkPicture.Assign(Value);
|
|
end;
|
|
|
|
procedure TdxSideBar.SetCanSelected(Value: Boolean);
|
|
begin
|
|
if (FCanSelected <> Value) then
|
|
begin
|
|
if (FSelectedItem <> nil) then
|
|
DoItemSelected(nil);
|
|
FCanSelected := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetGroupFont(Value: TFont);
|
|
begin
|
|
FGroupFont.Assign(Value);
|
|
RepaintAll;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetGroups(Value: TdxSideGroups);
|
|
begin
|
|
FGroups.Assign(Value);
|
|
ActiveGroupIndex := 0;
|
|
RepaintAll;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetGroupHeightOffSet(Value: Integer);
|
|
begin
|
|
if (FGroupHeightOffSet <> Value) and (Value > -1) and (Value < 10) then
|
|
begin
|
|
FGroupHeightOffSet := Value;
|
|
RepaintAll;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetItemFont(Value: TFont);
|
|
begin
|
|
FItemFont.Assign(Value);
|
|
RepaintAll;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetImages(AValue: TCustomImageList; var AImageList: TCustomImageList; AChangeLink: TChangeLink);
|
|
begin
|
|
if (AImageList <> AValue) then begin
|
|
if (AImageList <> nil) and not (csDestroying in AImageList.ComponentState) then
|
|
AImageList.UnRegisterChanges(AChangeLink);
|
|
AImageList := AValue;
|
|
if (AImageList <> nil) then
|
|
begin
|
|
AImageList.RegisterChanges(AChangeLink);
|
|
AImageList.FreeNotification(Self);
|
|
end;
|
|
RepaintAll;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetLargeImages(Value: TCustomImageList);
|
|
begin
|
|
SetImages(Value, FLargeImages, FLargeChangeLink);
|
|
end;
|
|
|
|
procedure TdxSideBar.SetSmallImages(Value: TCustomImageList);
|
|
begin
|
|
SetImages(Value, FSmallImages, FSmallChangeLink);
|
|
end;
|
|
|
|
procedure TdxSideBar.SetPaintStyle(Value: TdxsbPaintStyle);
|
|
begin
|
|
if (FPaintStyle <> Value) then
|
|
begin
|
|
FPaintStyle := Value;
|
|
FreeAndNil(FPainter);
|
|
if (BorderStyle <> bsNone) then
|
|
BorderStyle := bsNone
|
|
else if HandleAllocated then
|
|
RepaintAll;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetStore(Value: TdxSideBarStore);
|
|
begin
|
|
if (FStore <> Value) then begin
|
|
if not (csLoading in ComponentState) then
|
|
FGroups.Clear;
|
|
FActiveGroup := nil;
|
|
FMouseFocusedGroup := nil;
|
|
if not (csDestroying in ComponentState) {and (csDesigning in ComponentState)} then
|
|
RepaintAll;
|
|
if (FStore <> nil) and not (csDestroying in FStore.ComponentState) then
|
|
FStore.FBars.Remove(Self);
|
|
FStore := Value;
|
|
if (FStore <> nil) then
|
|
FStore.FBars.Add(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetTransparentImages(Value: Boolean);
|
|
begin
|
|
if (FTransparentImages <> Value) then begin
|
|
FTransparentImages := Value;
|
|
RepaintAll;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetScrollDelay(Value: Integer);
|
|
begin
|
|
if (Value > 0) and (FScrollTimer <> nil) then
|
|
FScrollTimer.Interval := Value;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetShowGroups(Value: Boolean);
|
|
begin
|
|
if (FShowGroups <> Value) then
|
|
begin
|
|
FShowGroups := Value;
|
|
RepaintAll;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetSpaceHeight(Value: Integer);
|
|
begin
|
|
if (FSpaceHeight <> Value) and (Value > 4) then begin
|
|
FSpaceHeight := Value;
|
|
InvalidateItems(True);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.OnChangeLink(Sender: TObject);
|
|
begin
|
|
RepaintAll;
|
|
end;
|
|
|
|
procedure TdxSideBar.OnFontChange(Sender: TObject);
|
|
begin
|
|
RepaintAll;
|
|
end;
|
|
|
|
procedure TdxSideBar.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
p: TPoint;
|
|
Group: TdxSideGroup;
|
|
Item: TdxSideBarItem;
|
|
begin
|
|
if (csDesigning in ComponentState) then
|
|
begin
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
Exit;
|
|
end;
|
|
if (Button = mbRight) then begin
|
|
PopupMenu := nil;
|
|
item := GetFocusedItem(X, Y);
|
|
if (item <> nil) then begin
|
|
if (item.StoredItem <> nil) and (item.StoredItem.PopupMenu <> nil) then
|
|
PopupMenu := item.StoredItem.PopupMenu
|
|
else PopupMenu := FItemPopupMenu;
|
|
end;
|
|
if (PopupMenu = nil) then
|
|
PopupMenu := FGroupPopupMenu;
|
|
end;
|
|
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
if (Button = mbLeft) then begin
|
|
// IsRenameGroup or Is RenameItem ?
|
|
if (IsEditing) then begin
|
|
EndEdit(True);
|
|
Exit;
|
|
end;
|
|
p.X := X;
|
|
p.Y := Y;
|
|
Group := GetGroupAtPos(p);
|
|
if (Group <> nil) then
|
|
DoGroupMouseFocused(Group, True)
|
|
else begin
|
|
if ViewInfo.IsPtTopScrollButton(p) then
|
|
begin
|
|
FScrollButtonUpIsDown := True;
|
|
FScrollTimer.Enabled := True;
|
|
FActiveGroup.TopVisibleItem:= FActiveGroup.TopVisibleItem - 1;
|
|
end else
|
|
if ViewInfo.IsPtBottomScrollButton(p) then
|
|
begin
|
|
FScrollButtonDownIsDown := True;
|
|
FScrollTimer.Enabled := True;
|
|
FActiveGroup.TopVisibleItem:= FActiveGroup.TopVisibleItem + 1;
|
|
end
|
|
else
|
|
begin
|
|
item := GetFocusedItem(X, Y);
|
|
if (item <> nil) then begin
|
|
DoItemMouseFocused(Item, True);
|
|
FMouseDownItem := FMouseFocusedItem;
|
|
if (CanSelected) then
|
|
DoItemSelected(Item);
|
|
FEnableDraging := True;
|
|
FPointDragging.X := X;
|
|
FPointDragging.Y := Y;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
Item: TdxSideBarItem;
|
|
Group: TdxSideGroup;
|
|
begin
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
if (csDesigning in ComponentState) then Exit;
|
|
|
|
if (GetCapture = Handle) then
|
|
ReleaseCapture;
|
|
if not (Button = mbLeft) or (IsGroupEditing) then Exit;
|
|
|
|
if (FMouseFocusedGroup <> nil) then
|
|
begin
|
|
DoGroupMouseFocused(FMouseFocusedGroup, False);
|
|
if (GetGroupAtPos(Point(X, Y)) = FMouseFocusedGroup) then
|
|
ActiveGroup := FMouseFocusedGroup
|
|
else
|
|
begin
|
|
Group := FMouseFocusedGroup;
|
|
FMouseFocusedGroup := nil;
|
|
InvalidateGroup(Group);
|
|
end;
|
|
end;
|
|
if FScrollButtonDownIsDown or FScrollButtonUpIsDown then begin
|
|
FScrollButtonDownIsDown := False;
|
|
FScrollButtonUpIsDown := False;
|
|
InvalidateScrollButtons;
|
|
end else
|
|
if not Dragging and FEnableDraging then begin
|
|
FEnableDraging := False;
|
|
item := GetFocusedItem(X, Y);
|
|
if (item <> nil) and (FMouseDownItem = item) then
|
|
DoItemClick(item);
|
|
end;
|
|
FMouseDownItem := nil;
|
|
end;
|
|
|
|
procedure TdxSideBar.MouseMove(Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
Item, OldItem: TdxSideBarItem;
|
|
Group: TdxSideGroup;
|
|
begin
|
|
inherited MouseMove(Shift, X, Y);
|
|
|
|
Group := GetGroupAtPos(Point(X, Y));
|
|
if not (ssLeft in Shift) then
|
|
DoGroupMouseFocused(Group, False)
|
|
else
|
|
if (FMouseFocusedGroup <> Group) then
|
|
begin
|
|
FMouseFocusedGroupIsDown := False;
|
|
if (FMouseFocusedGroup <> nil) then
|
|
InvalidateGroup(FMouseFocusedGroup);
|
|
end else
|
|
if (FMouseFocusedGroup <> nil) then
|
|
DoGroupMouseFocused(FMouseFocusedGroup, True);
|
|
OldItem := FMouseFocusedItem;
|
|
Item := GetFocusedItem(X, Y);
|
|
if not FEnableDraging then
|
|
DoItemMouseFocused(Item, False);
|
|
|
|
if not (csDesigning in ComponentState) and (DragMode = dmAutomatic) and FShowGroups then begin
|
|
if FEnableDraging and (((Item = nil) and (OldItem <> nil))
|
|
or ((Item <> nil) and ((X < FPointDragging.X - 5) or (X > FPointDragging.X + 5)
|
|
or (Y < FPointDragging.Y - 5) or (Y > FPointDragging.Y + 5)))) then begin
|
|
if (FMouseFocusedItem = nil) then
|
|
FMouseFocusedItem := OldItem;
|
|
inherited DragMode := dmAutomatic;
|
|
FEnableDraging := False;
|
|
BeginDrag(True);
|
|
end
|
|
else inherited DragMode := dmManual;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.WMEraseBkgnd(var Message: TWmEraseBkgnd);
|
|
begin
|
|
if (ActiveGroup = nil) then
|
|
inherited
|
|
else Message.Result := 1;
|
|
end;
|
|
|
|
procedure TdxSideBar.WMSetCursor(var Message: TWMSetCursor);
|
|
begin
|
|
if (FMouseFocusedGroup <> nil) then
|
|
SetCursor(Screen.Cursors[dxSideBarGroupCursor])
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxSideBar.WMSize(var Message: TWMSize);
|
|
begin
|
|
inherited;
|
|
Painter.NeedRecalViewInfo;
|
|
end;
|
|
|
|
procedure TdxSideBar.Paint;
|
|
begin
|
|
if FAssignFlag or IsMakingUpdate then
|
|
Exit;
|
|
|
|
Painter.Paint;
|
|
end;
|
|
|
|
procedure TdxSideBar.RepaintAll;
|
|
begin
|
|
if (csDestroying in ComponentState) or not HandleAllocated then
|
|
Exit;
|
|
|
|
ViewInfo.CalcViewInfo;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TdxSideBar.InvalidateGroup(AGroup: TdxSideGroup);
|
|
begin
|
|
if HandleAllocated then
|
|
Painter.InvalidateGroup(AGroup);
|
|
end;
|
|
|
|
procedure TdxSideBar.InvalidateItem(AItem: TdxSideBarItem);
|
|
begin
|
|
if HandleAllocated then
|
|
Painter.InvalidateItem(AItem);
|
|
end;
|
|
|
|
procedure TdxSideBar.InvalidateItemImage(AItem: TdxSideBarItem);
|
|
begin
|
|
if HandleAllocated then
|
|
Painter.InvalidateItemImage(AItem);
|
|
end;
|
|
|
|
procedure TdxSideBar.InvalidateItemBorder(AItem: TdxSideBarItem);
|
|
begin
|
|
if HandleAllocated then
|
|
Painter.InvalidateItemBorder(AItem);
|
|
end;
|
|
|
|
procedure TdxSideBar.InvalidateItems(AUpdateCalcInfo: Boolean);
|
|
begin
|
|
if HandleAllocated then
|
|
begin
|
|
if AUpdateCalcInfo then
|
|
ViewInfo.CalcViewInfo;
|
|
Painter.InvalidateItems;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.InvalidateScrollButtons;
|
|
begin
|
|
if HandleAllocated then
|
|
Painter.InvalidateScrollButtons;
|
|
end;
|
|
|
|
procedure TdxSideBar.WndProc(var Message: TMessage);
|
|
begin
|
|
if (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
|
|
HintActivate(False);
|
|
inherited WndProc(Message);
|
|
end;
|
|
|
|
function TdxSideBar.GetVisibleGroup(Index: Integer): TdxSideGroup;
|
|
var
|
|
i, AIndex: Integer;
|
|
begin
|
|
Result := nil;
|
|
AIndex := 0;
|
|
for i := 0 to Groups.Count - 1 do
|
|
if Groups[i].Visible then
|
|
begin
|
|
if (AIndex = Index) then
|
|
begin
|
|
Result := Groups[i];
|
|
break;
|
|
end;
|
|
Inc(AIndex);
|
|
end;
|
|
end;
|
|
|
|
function TdxSideBar.GetVisibleIndexByGroup(AGroup: TdxSideGroup): Integer;
|
|
var
|
|
i, VisibleIndex: Integer;
|
|
begin
|
|
Result := -1;
|
|
VisibleIndex := 0;
|
|
for i := 0 to Groups.Count - 1 do
|
|
if Groups[i].Visible then
|
|
begin
|
|
if (Groups[i] = AGroup) then
|
|
begin
|
|
Result := VisibleIndex;
|
|
break;
|
|
end;
|
|
Inc(VisibleIndex);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.DoHintTimer(Sender: TObject);
|
|
begin
|
|
HintActivate(False);
|
|
FHintTimer.Enabled := False;
|
|
end;
|
|
|
|
procedure TdxSideBar.DoScrollTimer(Sender: TObject);
|
|
begin
|
|
FScrollButtonUpIsDown := FScrollButtonUpIsDown and ViewInfo.IsTopScrollButtonVisible;
|
|
FScrollButtonDownIsDown := FScrollButtonDownIsDown and ViewInfo.IsBottomScrollButtonVisible;
|
|
|
|
if FScrollButtonUpIsDown or FScrollButtonDownIsDown then begin
|
|
FDestDropItem := nil;
|
|
FDropItemPosition := sbdspIn;
|
|
if FScrollButtonUpIsDown then
|
|
ActiveGroup.TopVisibleItem:= ActiveGroup.TopVisibleItem - 1;
|
|
if FScrollButtonDownIsDown then
|
|
ActiveGroup.TopVisibleItem := ActiveGroup.TopVisibleItem + 1;
|
|
end else FScrollTimer.Enabled := False;
|
|
end;
|
|
|
|
procedure TdxSideBar.HintActivate(AShow: Boolean);
|
|
var
|
|
r: TRect;
|
|
p: TPoint;
|
|
AHint: string;
|
|
AItemViewInfo: TdxSideItemViewInfo;
|
|
begin
|
|
FHintWindowShowing := False;
|
|
AShow := AShow and (FMouseFocusedItem <> nil) and (FMouseFocusedItem.Hint <> '');
|
|
if IsWindowVisible(HintWindow.Handle) then
|
|
ShowWindow(HintWindow.Handle, SW_HIDE);
|
|
if AShow and not Dragging and Application.Active then
|
|
begin
|
|
AItemViewInfo := ViewInfo.GetItemViewInfoByItem(FMouseFocusedItem);
|
|
if AItemViewInfo <> nil then
|
|
begin
|
|
if (not AItemViewInfo.IsPartialVisible) then
|
|
r := AItemViewInfo.CaptionRect
|
|
else r := AItemViewInfo.ImageRect;
|
|
end;
|
|
p.Y := r.Bottom + 2;
|
|
p.X := 0;
|
|
p := ClientToScreen(p);
|
|
SetRect(r, 0, 0, Width - 2 * FSpaceHeight, 0);
|
|
AHint := GetShortHint(FMouseFocusedItem.Hint);
|
|
r := HintWindow.CalcHintRect(r.Right - r.Left, AHint, nil);
|
|
if (FMouseFocusedItem.Group.IconType = dxsgLargeIcon) then
|
|
Inc(p.X , (Width - r.Right + r.Left) div 2)
|
|
else Inc(p.X , FSpaceHeight);
|
|
OffsetRect(r, p.X, p.Y);
|
|
InflateRect(r, 1, 1);
|
|
FHintTimer.Enabled := False;
|
|
HintWindow.Color := Application.HintColor;
|
|
HintWindow.ActivateHint(r, AHint);
|
|
FHintWindowShowing := True;
|
|
FHintTimer.Enabled := True;
|
|
end
|
|
else
|
|
FHintTimer.Enabled := False;
|
|
end;
|
|
|
|
function TdxSideBar.GetGroupAtPos(p: TPoint): TdxSideGroup;
|
|
begin
|
|
Result := ViewInfo.GetGroupAtPos(p);
|
|
end;
|
|
|
|
function TdxSideBar.GetPopupGroup: TdxSideGroup;
|
|
var
|
|
p: TPoint;
|
|
begin
|
|
GetCursorPos(p);
|
|
p := ScreenToCLient(p);
|
|
Result := GetGroupAtPos(p);
|
|
if (Result = nil) then
|
|
Result := FActiveGroup;
|
|
end;
|
|
|
|
function TdxSideBar.GetItemAtPos(p: TPoint): TdxSideBarItem;
|
|
begin
|
|
Result := ViewInfo.GetItemAtPos(p);
|
|
end;
|
|
|
|
function TdxSideBar.IsGroupEditing: Boolean;
|
|
begin
|
|
Result := FRenameGroup <> nil;
|
|
end;
|
|
|
|
function TdxSideBar.IsItemEditing: Boolean;
|
|
begin
|
|
Result := FRenameItem <> nil;
|
|
end;
|
|
|
|
function TdxSideBar.IsEditing: Boolean;
|
|
begin
|
|
Result := IsGroupEditing or IsItemEditing;
|
|
end;
|
|
|
|
procedure TdxSideBar.EditGroup(Group: TdxSideGroup);
|
|
var
|
|
r: TRect;
|
|
begin
|
|
if (FRenameGroup <> nil) or (FRenameItem <> nil) then
|
|
EndEdit(True);
|
|
FRenameGroup := Group;
|
|
|
|
FRenameEdit := TSideBarRenameEdit.Create(Self);
|
|
r := ViewInfo.GetGroupViewInfoByGroup(Group).Rect;
|
|
with FRenameEdit do begin
|
|
Parent := Self;
|
|
BorderStyle := bsNone;
|
|
OnExit := RenameEditExit;
|
|
Font := FGroupFont;
|
|
Top := r.Top;
|
|
Left := r.Left;
|
|
Width := r.Right - r.Left;
|
|
Height := r.Bottom - r.Top;
|
|
Text := Group.Caption;
|
|
Font := FGroupFont;
|
|
Font.Color := clWindowText;
|
|
end;
|
|
CallNotify(FOnBeforeEdit, Self);
|
|
FRenameEdit.SetFocus;
|
|
end;
|
|
|
|
procedure TdxSideBar.EditItem(Item: TdxSideBarItem);
|
|
var
|
|
r: TRect;
|
|
AItemViewInfo: TdxSideItemViewInfo;
|
|
begin
|
|
if (FRenameGroup <> nil) or (FRenameItem <> nil) then
|
|
EndEdit(True);
|
|
|
|
ActiveGroup := Item.Group;
|
|
Item.MakeVisible;
|
|
|
|
AItemViewInfo := ViewInfo.GetItemViewInfoByItem(Item);
|
|
if AItemViewInfo = nil then
|
|
exit;
|
|
|
|
FRenameItem := Item;
|
|
FRenameEdit := TSideBarRenameEdit.Create(Self);
|
|
FRenameEdit.Font.Assign(ItemFont);
|
|
r := AItemViewInfo.CaptionRect;
|
|
InflateRect(r, 2, 2);
|
|
with FRenameEdit do begin
|
|
Parent := Self;
|
|
BorderStyle := bsNone;
|
|
OnExit := RenameEditExit;
|
|
Font := FGroupFont;
|
|
Top := r.Top;
|
|
Left := r.Left;
|
|
Width := r.Right - r.Left + 2;
|
|
Height := r.Bottom - r.Top;
|
|
Font := FItemFont;
|
|
Font.Color := clWindowText;
|
|
Text := Item.Caption;
|
|
end;
|
|
CallNotify(FOnBeforeEdit, Self);
|
|
FRenameEdit.SetFocus;
|
|
SendMessage(FRenameEdit.Handle, EM_SETSEL, 0, 1000);
|
|
end;
|
|
|
|
procedure TdxSideBar.EndEdit(Accept: Boolean);
|
|
begin
|
|
if (FRenameEdit.Text <> '') and Accept then
|
|
begin
|
|
if (FRenameGroup <> nil) then
|
|
FRenameGroup.Caption := FRenameEdit.Text;
|
|
if (FRenameItem <> nil) then
|
|
FRenameItem.Caption := FRenameEdit.Text;
|
|
end;
|
|
CallNotify(FOnAfterEdit, Self);
|
|
FRenameEdit.Free;
|
|
FRenameEdit := nil;
|
|
FRenameGroup := nil;
|
|
FRenameItem := nil;
|
|
RepaintAll;
|
|
end;
|
|
|
|
function TdxSideBar.GetLargeImages: TCustomImageList;
|
|
begin
|
|
Result := FLargeImages;
|
|
if (Result = nil) and (Store <> nil) then
|
|
Result := Store.FLargeImages;
|
|
end;
|
|
|
|
function TdxSideBar.GetSmallImages: TCustomImageList;
|
|
begin
|
|
Result := FSmallImages;
|
|
if (Result = nil) and (Store <> nil) then
|
|
Result := Store.FSmallImages;
|
|
end;
|
|
|
|
procedure TdxSideBar.RenameEditExit(Sender: TObject);
|
|
begin
|
|
EndEdit(True);
|
|
end;
|
|
|
|
procedure TdxSideBar.DoItemClick(Item: TdxSideBarItem);
|
|
begin
|
|
if (Item <> nil) and not Item.Enabled then Exit;
|
|
if (Item <> nil) and (Item.StoredItem <> nil) then
|
|
Item.StoredItem.DoClick(Self, Item);
|
|
if (Assigned(FOnItemClick))
|
|
and ((Item.StoredItem = nil) or not Assigned(Item.StoredItem.FOnClick)) then
|
|
FOnItemClick(Self, Item);
|
|
end;
|
|
|
|
function TdxSideBar.GetFocusedItem(X, Y: Integer): TdxSideBarItem;
|
|
var
|
|
p: TPoint;
|
|
begin
|
|
p.X := X;
|
|
p.Y := Y;
|
|
Result := GetItemAtPos(p);
|
|
end;
|
|
|
|
function TdxSideBar.GetTopVisibleToMakeItemVisible(AItem: TdxSideBarItem): Integer;
|
|
var
|
|
OldTopVisible: Integer;
|
|
begin
|
|
Result := 0;
|
|
if ViewInfo.ItemCount = 0 then exit;
|
|
if AItem.Index < ViewInfo.Items[0].Item.Index then
|
|
Result := AItem.Index
|
|
else
|
|
begin
|
|
OldTopVisible := ActiveGroup.TopVisibleItem;
|
|
while not AItem.IsFullVisible and (ActiveGroup.FTopVisibleItem < ActiveGroup.Items.Count - 1) do
|
|
begin
|
|
ActiveGroup.FTopVisibleItem := ActiveGroup.FTopVisibleItem + 1;
|
|
Result := ActiveGroup.TopVisibleItem;
|
|
ViewInfo.CalcViewInfo;
|
|
end;
|
|
ActiveGroup.FTopVisibleItem := OldTopVisible;
|
|
ViewInfo.CalcViewInfo;
|
|
end;
|
|
end;
|
|
|
|
function TdxSideBar.GetDestDropItemViewInfo: TdxSideItemViewInfo;
|
|
begin
|
|
if DestDropItem <> nil then
|
|
Result := ViewInfo.GetItemViewInfo(DestDropItem)
|
|
else Result := nil;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetMouseFocusedItem(Item: TdxSideBarItem);
|
|
begin
|
|
if (Item <> FMouseFocusedItem) then begin
|
|
FMouseFocusedItem := Item;
|
|
CallNotify(FOnChangeFocusedItem, Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetSelectedItem(Item: TdxSideBarItem);
|
|
begin
|
|
if (Item <> FSelectedItem) then
|
|
begin
|
|
FSelectedItem := Item;
|
|
CallNotify(FOnChangeSelectedItem, Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.DoGroupMouseFocused(Group: TdxSideGroup; IsDown: Boolean);
|
|
var
|
|
OldGroup: TdxSideGroup;
|
|
OldDown: Boolean;
|
|
begin
|
|
if (FMouseFocusedGroup <> Group) or (FMouseFocusedGroupIsDown <> IsDown) then begin
|
|
OldGroup := FMouseFocusedGroup;
|
|
FMouseFocusedGroup := Group;
|
|
OldDown := IsDown;
|
|
FMouseFocusedGroupIsDown := IsDown;
|
|
if (OldGroup <> nil) and ((OldGroup <> Group) or (IsDown = OldDown))
|
|
and Painter.IsGroupFocused then
|
|
InvalidateGroup(OldGroup);
|
|
if (Group <> nil) and (OldGroup <> Group) and Painter.IsGroupFocused then
|
|
InvalidateGroup(Group);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.DoItemMouseFocused(Item: TdxSideBarItem; IsDown: Boolean);
|
|
var
|
|
ANeedShowHint: Boolean;
|
|
begin
|
|
if (FMouseFocusedItem <> Item) or (FMouseFocusedItemIsDown <> IsDown) then begin
|
|
if (FMouseFocusedItem <> nil) and (FMouseFocusedItem <> Item) and(FMouseFocusedItem <> FSelectedItem) then
|
|
InvalidateItemBorder(FMouseFocusedItem);
|
|
ANeedShowHint := ShowHint and (Item <> FMouseFocusedItem);
|
|
if ANeedShowHint then
|
|
HintActivate(False);
|
|
SetMouseFocusedItem(Item);
|
|
if not IsDown and ANeedShowHint then
|
|
HintActivate(True);
|
|
FMouseFocusedItemIsDown := IsDown;
|
|
if (FMouseFocusedItem <> nil) and(FMouseFocusedItem <> FSelectedItem) and FMouseFocusedItem.Enabled then
|
|
InvalidateItemBorder(FMouseFocusedItem);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.DoItemSelected(Item: TdxSideBarItem);
|
|
begin
|
|
if not CanSelected then Exit;
|
|
if (FSelectedItem <> Item) and (FSelectedItem <> nil) then
|
|
InvalidateItemBorder(FSelectedItem);
|
|
|
|
SetSelectedItem(Item);
|
|
|
|
if (FSelectedItem <> nil) and (FSelectedItem.Collection <> nil)
|
|
and FSelectedItem.Enabled then
|
|
InvalidateItemBorder(FSelectedItem);
|
|
end;
|
|
|
|
procedure TdxSideBar.DoBkPictureChange(Sender: TObject);
|
|
begin
|
|
RepaintAll;
|
|
end;
|
|
|
|
procedure TdxSideBar.CMMouseEnter(var Message: TMessage);
|
|
begin
|
|
inherited;
|
|
CallNotify(FOnMouseEnter, Self);
|
|
end;
|
|
|
|
procedure TdxSideBar.CMMouseLeave(var Message: TMessage);
|
|
var
|
|
Group: TdxSideGroup;
|
|
begin
|
|
inherited;
|
|
if (dxSideBarDragObject <> nil) then
|
|
SetDestDropItemandPosition(nil, sbdspIn)
|
|
else DoItemMouseFocused(nil, False);
|
|
CallNotify(FOnMouseLeave, Self);
|
|
if (FMouseFocusedGroup <> nil) then
|
|
begin
|
|
Group := FMouseFocusedGroup;
|
|
FMouseFocusedGroup := nil;
|
|
InvalidateGroup(Group);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetDestDropItemandPosition(AItem: TdxSideBarItem; APosition: TdxSideBarDragSourcePosition);
|
|
var
|
|
OldItemViewInfo: TdxSideItemViewInfo;
|
|
OldPosition: TdxSideBarDragSourcePosition;
|
|
|
|
procedure InvalidateSpace(AItemViewInfo: TdxSideItemViewInfo; APosition: TdxSideBarDragSourcePosition);
|
|
var
|
|
r: TRect;
|
|
begin
|
|
if (AItemViewInfo <> nil) then
|
|
begin
|
|
r := AItemViewInfo.GetItemDragSourceSpace(APosition);
|
|
InflateRect(r, 0, 1);
|
|
cxInvalidateRect(Handle, r, True);
|
|
end;
|
|
end;
|
|
|
|
procedure InvalidateArrow;
|
|
begin
|
|
InvalidateSpace(OldItemViewInfo, OldPosition);
|
|
InvalidateSpace(DestDropItemViewInfo, DropItemPosition);
|
|
end;
|
|
|
|
begin
|
|
if (DestDropItem = AItem) and (DropItemPosition = APosition) then
|
|
exit;
|
|
OldItemViewInfo := DestDropItemViewInfo;
|
|
OldPosition := FDropItemPosition;
|
|
FDestDropItem := AItem;
|
|
FDropItemPosition := APosition;
|
|
InvalidateArrow;
|
|
end;
|
|
|
|
procedure TdxSideBar.SetDestDropItem(Value: TdxSideBarItem);
|
|
begin
|
|
SetDestDropItemandPosition(Value, DropItemPosition);
|
|
end;
|
|
|
|
procedure TdxSideBar.SetDropItemPosition(Value: TdxSideBarDragSourcePosition);
|
|
begin
|
|
SetDestDropItemandPosition(DestDropItem, Value);
|
|
end;
|
|
|
|
procedure TdxSideBar.DragOver(Source: TObject; X, Y: Integer; State: TDragState;
|
|
var Accept: Boolean);
|
|
|
|
procedure DoDragOver;
|
|
begin
|
|
if Assigned(OnDragOver) then
|
|
OnDragOver(Self, Source, X, Y, State, Accept);
|
|
end;
|
|
|
|
var
|
|
p: TPoint;
|
|
r: TRect;
|
|
AItemViewInfo: TdxSideItemViewInfo;
|
|
APosition: TdxSideBarDragSourcePosition;
|
|
begin
|
|
if (dxSideBarDragObject = nil) or (ActiveGroup = nil) then begin
|
|
Accept := ActiveGroup = nil;
|
|
DoDragOver;
|
|
Exit;
|
|
end;
|
|
|
|
p := Point(X, Y);
|
|
Accept := False;
|
|
|
|
if (GetGroupAtPos(p) <> nil) then begin
|
|
ActiveGroup := GetGroupAtPos(p);
|
|
DoDragOver;
|
|
Exit;
|
|
end;
|
|
|
|
if not FScrollTimer.Enabled then
|
|
FScrollTimer.Enabled := True;
|
|
|
|
FScrollButtonUpIsDown := False;
|
|
FScrollButtonDownIsDown := False;
|
|
if ViewInfo.IsTopScrollButtonVisible then begin
|
|
r := ViewInfo.ItemsRect;
|
|
r.Bottom := r.Top + SpaceHeight + ScrollButtonHeight;
|
|
if (Y > r.Top) and (Y < r.Bottom) then begin
|
|
FScrollButtonUpIsDown := True;
|
|
DoItemMouseFocused(nil, False);
|
|
DoDragOver;
|
|
Exit;
|
|
end;
|
|
end;
|
|
if ViewInfo.IsBottomScrollButtonVisible then
|
|
begin
|
|
r := ViewInfo.ItemsRect;
|
|
r.Top := r.Bottom - SpaceHeight - ScrollButtonHeight;
|
|
if (Y > r.Top) and (Y < r.Bottom) then begin
|
|
FScrollButtonDownIsDown := True;
|
|
DoItemMouseFocused(nil, False);
|
|
DoDragOver;
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
DoItemMouseFocused(GetFocusedItem(X, Y), False);
|
|
|
|
AItemViewInfo := ViewInfo.GetNearestItemViewInfoAtPost(p, APosition);
|
|
SetDestDropItemandPosition(GetViewInfoItem(AItemViewInfo), APosition);
|
|
Accept := (APosition <> sbdspIn) or (AItemViewInfo <> nil);
|
|
DoDragOver;
|
|
end;
|
|
|
|
procedure TdxSideBar.DoEndDrag(Target: TObject; X, Y: Integer);
|
|
begin
|
|
if (dxSideBarDragObject <> nil) then
|
|
begin
|
|
dxSideBarDragObject.EndDrag(Target, X, Y);
|
|
FDropItemPosition := sbdspIn;
|
|
if Target = nil then
|
|
RepaintAll;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxSideBar.DoStartDrag(var DragObject: TDragObject);
|
|
var
|
|
Item: TdxSideBarItem;
|
|
p: TPoint;
|
|
begin
|
|
inherited;
|
|
GetCursorPos(p);
|
|
p := ScreenToClient(p);
|
|
Item := FMouseFocusedItem;
|
|
if (Item <> nil) then begin
|
|
dxSideBarDragObject := TdxSideBarDragObject.Create(Self, DragObject, Item, nil);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBar.LoadFromRegistry(ARegistryPath: string);
|
|
var
|
|
Registry: TRegistry;
|
|
|
|
function GetStoredItemByName(ASt: string): TdxStoredSideItem;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
if (ASt <> '') and (Store <> nil) then
|
|
for I := 0 to Store.Count - 1 do
|
|
if (CompareText(Store.Items[I].Name, ASt) = 0) then
|
|
begin
|
|
Result := Store.Items[I];
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
procedure ReadGroupItems(const AKey: string; AGroup: TdxSideGroup);
|
|
var
|
|
I, ItemCount: Integer;
|
|
begin
|
|
with Registry do
|
|
begin
|
|
if ValueExists('ItemCount') then ItemCount := ReadInteger('ItemCount')
|
|
else ItemCount := 0;
|
|
CloseKey;
|
|
for I := 0 to ItemCount - 1 do
|
|
if OpenKey(AKey + '\Item' + IntToStr(I), False) then
|
|
with AGroup.Items.Add do
|
|
try
|
|
if (Store <> nil) then
|
|
StoredItem := GetStoredItemByName(ReadString('StoredItem'));
|
|
Caption := ReadString('Caption');
|
|
CustomData := ReadString('CustomData');
|
|
Hint := ReadString('Hint');
|
|
IsDefault := ReadBool('IsDefault');
|
|
LargeImage := ReadInteger('LargeImage');
|
|
SmallImage := ReadInteger('SmallImage');
|
|
Tag := ReadInteger('Tag');
|
|
finally
|
|
CloseKey;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
AGroupCount: Integer;
|
|
AGroup: TdxSideGroup;
|
|
I: Integer;
|
|
AKey: string;
|
|
begin
|
|
Registry := TRegistry.Create;
|
|
with Registry do
|
|
if OpenKey(ARegistryPath, False) then
|
|
begin
|
|
if ValueExists('GroupCount') then AGroupCount := ReadInteger('GroupCount')
|
|
else AGroupCount := 0;
|
|
|
|
if (AGroupCount > 0) then
|
|
Groups.Clear;
|
|
|
|
for I := 0 to AGroupCount - 1 do
|
|
begin
|
|
AGroup := Groups.Add;
|
|
AKey := ARegistryPath + '\Group' + IntToStr(I);
|
|
if OpenKey(AKey, False) then
|
|
begin
|
|
AGroup.Caption := ReadString('Caption');
|
|
AGroup.IconType := TdxSideGroupIconType(ReadInteger('IconType'));
|
|
ReadGroupItems(AKey, AGroup);
|
|
end;
|
|
end;
|
|
end;
|
|
Registry.Free;
|
|
end;
|
|
|
|
procedure TdxSideBar.SaveToRegistry(ARegistryPath: string);
|
|
var
|
|
Registry, SubRegistry: TRegistry;
|
|
Keys, SubKeys: TStringList;
|
|
|
|
procedure WriteGroupItems(const AKey: string; AGroup: TdxSideGroup);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
with Registry do
|
|
begin
|
|
WriteInteger('ItemCount', AGroup.ItemCount);
|
|
CloseKey;
|
|
for I := 0 to AGroup.ItemCount - 1 do
|
|
if OpenKey(AKey + '\Item' + IntToStr(I), True) then
|
|
with AGroup.Items[I] do
|
|
begin
|
|
WriteString('Caption', Caption);
|
|
WriteString('CustomData', CustomData);
|
|
WriteString('Hint', Hint);
|
|
WriteBool('IsDefault', IsDefault);
|
|
WriteInteger('LargeImage', LargeImage);
|
|
WriteInteger('SmallImage', SmallImage);
|
|
WriteInteger('Tag', Tag);
|
|
if (StoredItem <> nil) then
|
|
WriteString('StoredItem', StoredItem.Name);
|
|
CloseKey;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
I, j: Integer;
|
|
AKey: string;
|
|
begin
|
|
if (ARegistryPath = '') then
|
|
Exit;
|
|
|
|
Registry := TRegistry.Create;
|
|
with Registry do
|
|
if OpenKey(ARegistryPath, True) then
|
|
begin
|
|
// delete entire previous data from registry
|
|
Keys := TStringList.Create;
|
|
SubKeys := TStringList.Create;
|
|
SubRegistry := TRegistry.Create;
|
|
try
|
|
GetKeyNames(Keys);
|
|
for I := 0 to Keys.Count - 1 do
|
|
begin
|
|
with SubRegistry do
|
|
begin
|
|
OpenKey(ARegistryPath + '\' + Keys[I], False);
|
|
SubRegistry.GetKeyNames(SubKeys);
|
|
for j := 0 to SubKeys.Count - 1 do DeleteKey(SubKeys[j]);
|
|
CloseKey;
|
|
end;
|
|
DeleteKey(Keys[I]);
|
|
end;
|
|
finally
|
|
SubRegistry.Free;
|
|
SubKeys.Free;
|
|
Keys.Free;
|
|
end;
|
|
|
|
// write group count
|
|
WriteInteger('GroupCount', Groups.Count);
|
|
|
|
// write Groups
|
|
for I := 0 to GroupCount - 1 do
|
|
begin
|
|
AKey := ARegistryPath + '\Group' + IntToStr(I);
|
|
if OpenKey(AKey, True) then
|
|
begin
|
|
WriteString('Caption', Groups[I].Caption);
|
|
WriteInteger('IconType', Ord(Groups[I].IconType));
|
|
WriteGroupItems(AKey, Groups[I]);
|
|
end;
|
|
end;
|
|
end;
|
|
Registry.Free;
|
|
end;
|
|
|
|
function TdxSideBar.CreatePainter: TdxSideBarPainter;
|
|
const
|
|
PainterClasses: Array[TdxsbPaintStyle] of TdxSideBarPainterClass =
|
|
(TdxSideBarStandardPainter,
|
|
TdxSideBarFlatPainter,
|
|
TdxSideBarXPPainter,
|
|
TdxSideBarW2kPainter);
|
|
begin
|
|
Result := PainterClasses[PaintStyle].Create(self);
|
|
end;
|
|
|
|
function TdxSideBar.VisibleGroupCount: Integer;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := 0;
|
|
for i := 0 to Groups.Count - 1 do
|
|
if Groups[i].Visible then
|
|
Inc(Result);
|
|
end;
|
|
|
|
{TdxSideBarPainter}
|
|
constructor TdxSideBarPainter.Create(ASideBar: TdxSideBar);
|
|
begin
|
|
inherited Create;
|
|
FSideBar := ASideBar;
|
|
FViewInfo := CreateViewInfo;
|
|
end;
|
|
|
|
destructor TdxSideBarPainter.Destroy;
|
|
begin
|
|
FViewInfo.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TdxSideBarPainter.IsGroupFocused: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.Paint;
|
|
begin
|
|
if (SideBar.ActiveGroup <> nil) and (SideBar.FOldActiveGroup <> nil)
|
|
and (SideBar.ActiveGroup <> SideBar.FOldActiveGroup)
|
|
and (ViewInfo.GroupCount > 0) then
|
|
ScrollGroups;
|
|
SideBar.FOldActiveGroup := nil;
|
|
|
|
if not ViewInfo.IsReady then
|
|
ViewInfo.CalcViewInfo;
|
|
|
|
DrawGroups;
|
|
DrawBorder;
|
|
DrawScrollButtons;
|
|
DrawItems;
|
|
DrawFillRect(SideBar.ClientRect);
|
|
DrawDragDestinationArrow;
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.InvalidateGroup(AGroup: TdxSideGroup);
|
|
var
|
|
AGroupViewInfo: TdxSideGroupViewInfo;
|
|
begin
|
|
AGroupViewInfo := ViewInfo.GetGroupViewInfoByGroup(AGroup);
|
|
if (AGroupViewInfo <> nil) then
|
|
cxInvalidateRect(SideBar.Handle, AGroupViewInfo.Rect, True);
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.InvalidateItem(AItem: TdxSideBarItem);
|
|
var
|
|
Rgn1, Rgn2: HRGN;
|
|
AItemViewInfo: TdxSideItemViewInfo;
|
|
begin
|
|
AItemViewInfo := ViewInfo.GetItemViewInfoByItem(AItem);
|
|
if (AItemViewInfo = nil) then exit;
|
|
with AItemViewInfo.ImageRect do
|
|
Rgn1 := CreateRectRgn(Left - 1, Top - 1, Right + 1, Bottom + 1);
|
|
with AItemViewInfo.CaptionRect do
|
|
Rgn2 := CreateRectRgn(Left, Top, Right, Bottom);
|
|
CombineRgn(Rgn1, Rgn1, Rgn2, RGN_OR);
|
|
DeleteObject(Rgn2);
|
|
with ViewInfo.ItemsRect do
|
|
Rgn2 := CreateRectRgn(Left, Top, Right, Bottom);
|
|
CombineRgn(Rgn1, Rgn1, Rgn2, RGN_AND);
|
|
DeleteObject(Rgn2);
|
|
Windows.InvalidateRgn(SideBar.Handle, Rgn1, True);
|
|
DeleteObject(Rgn1);
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.InvalidateItemImage(AItem: TdxSideBarItem);
|
|
var
|
|
ARect: TRect;
|
|
AItemViewInfo: TdxSideItemViewInfo;
|
|
begin
|
|
AItemViewInfo := ViewInfo.GetItemViewInfoByItem(AItem);
|
|
if (AItemViewInfo <> nil) then
|
|
begin
|
|
ARect := AItemViewInfo.ImageRect;
|
|
if ARect.Bottom > ViewInfo.ItemsRect.Bottom then
|
|
ARect.Bottom := ViewInfo.ItemsRect.Bottom;
|
|
cxInvalidateRect(SideBar.Handle, ARect, True);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.InvalidateItemBorder(AItem: TdxSideBarItem);
|
|
var
|
|
AItemViewInfo: TdxSideItemViewInfo;
|
|
Rgn1, Rgn2: HRGN;
|
|
begin
|
|
AItemViewInfo := ViewInfo.GetItemViewInfoByItem(AItem);
|
|
if AItemViewInfo <> nil then
|
|
begin
|
|
with AItemViewInfo.ItemRect do
|
|
Rgn1 := CreateRectRgn(Left - 1, Top - 1, Right + 1, Bottom + 1);
|
|
with AItemViewInfo.ImageRect do
|
|
Rgn2 := CreateRectRgn(Left, Top, Right, Bottom);
|
|
CombineRgn(Rgn1, Rgn1, Rgn2, RGN_XOR);
|
|
DeleteObject(Rgn2);
|
|
with ViewInfo.ItemsRect do
|
|
Rgn2 := CreateRectRgn(Left, Top, Right, Bottom);
|
|
CombineRgn(Rgn1, Rgn1, Rgn2, RGN_AND);
|
|
DeleteObject(Rgn2);
|
|
Windows.InvalidateRgn(SideBar.Handle, Rgn1, True);
|
|
DeleteObject(Rgn1);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.InvalidateItems;
|
|
var
|
|
Rgn1, Rgn2: HRGN;
|
|
i: Integer;
|
|
begin
|
|
with ViewInfo.GetPaintRect do
|
|
Rgn1 := CreateRectRgn(Left, Top, Right, Bottom);
|
|
for i := 0 to ViewInfo.GroupCount - 1 do
|
|
begin
|
|
with ViewInfo.Groups[i].Rect do
|
|
Rgn2 := CreateRectRgn(Left, Top, Right, Bottom);
|
|
CombineRgn(Rgn1, Rgn1, Rgn2, RGN_XOR);
|
|
DeleteObject(Rgn2);
|
|
end;
|
|
Windows.InvalidateRgn(SideBar.Handle, Rgn1, True);
|
|
DeleteObject(Rgn1);
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.InvalidateScrollButtons;
|
|
var
|
|
Rgn1, Rgn2: HRGN;
|
|
begin
|
|
if not ViewInfo.IsTopScrollButtonVisible and not ViewInfo.IsTopScrollButtonVisible then
|
|
exit;
|
|
with ViewInfo.TopScrollButtonRect do
|
|
Rgn1 := CreateRectRgn(Left, Top, Right, Bottom);
|
|
with ViewInfo.BottomScrollButtonRect do
|
|
Rgn2 := CreateRectRgn(Left, Top, Right, Bottom);
|
|
CombineRgn(Rgn1, Rgn1, Rgn2, RGN_OR);
|
|
Windows.InvalidateRgn(SideBar.Handle, Rgn1, True);
|
|
DeleteObject(Rgn1);
|
|
DeleteObject(Rgn2);
|
|
end;
|
|
|
|
function TdxSideBarPainter.CreateViewInfo: TdxSideBarViewInfo;
|
|
begin
|
|
Result := TdxSideBarViewInfo.Create(self);
|
|
end;
|
|
|
|
function TdxSideBarPainter.Canvas: TCanvas;
|
|
begin
|
|
Result := SideBar.Canvas;
|
|
end;
|
|
|
|
function TdxSideBarPainter.DC: HDC;
|
|
begin
|
|
Result := Canvas.Handle;
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.NeedRecalViewInfo;
|
|
begin
|
|
ViewInfo.Unready;
|
|
end;
|
|
|
|
function TdxSideBarPainter.ClientHeight: Integer;
|
|
begin
|
|
Result := SideBar.ClientHeight;
|
|
end;
|
|
|
|
function TdxSideBarPainter.ClientWidth: Integer;
|
|
begin
|
|
Result := SideBar.ClientWidth;
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.ExcludeClipRect(ARect: TRect);
|
|
begin
|
|
Windows.ExcludeClipRect(DC, ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.IntersectClipRect(ARect: TRect);
|
|
begin
|
|
Windows.IntersectClipRect(DC, ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.DrawBorder;
|
|
begin
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.ScrollGroups;
|
|
|
|
function IsTopScrolling: Boolean;
|
|
begin
|
|
Result := SideBar.FOldActiveGroup.Index > SideBar.ActiveGroup.Index;
|
|
end;
|
|
|
|
var
|
|
r, rs: TRect;
|
|
FStep, FdStep: Integer;
|
|
FirstTime, NextTime: Integer;
|
|
AIndex: Integer;
|
|
begin
|
|
if(SideBar.FOldActiveGroup = nil) then exit;
|
|
r := ViewInfo.ItemsRect;
|
|
r.Left := ViewInfo.GetPaintRect.Left;
|
|
r.Right := ViewInfo.GetPaintRect.Right;
|
|
if IsTopScrolling then
|
|
begin
|
|
AIndex := ViewInfo.GetGroupViewInfoByGroup(SideBar.ActiveGroup).Index;
|
|
r.Top := ViewInfo.GetGroup(AIndex).Rect.Bottom;
|
|
if(AIndex + 1 < ViewInfo.GroupCount) then
|
|
r.Bottom := ViewInfo.GetGroup(AIndex + 1).Rect.Top;
|
|
FdStep := 1;
|
|
end
|
|
else
|
|
begin
|
|
AIndex := ViewInfo.GetGroupViewInfoByGroup(SideBar.ActiveGroup).Index;
|
|
r.Top := ViewInfo.GetGroup(AIndex).Rect.Bottom;
|
|
if(AIndex + 1 < ViewInfo.GroupCount) then
|
|
r.Bottom := ViewInfo.GetGroup(AIndex + 1).Rect.Top;
|
|
FdStep := -1;
|
|
end;
|
|
|
|
FirstTime := GetTickCount;
|
|
FStep := dxSideBarGroupScrollStep;
|
|
while (r.Bottom - r.Top > ViewInfo.GetGroupHeight) do
|
|
begin
|
|
ScrollWindowEx(SideBar.Handle, 0, FStep * FdStep, @r, @r, 0, nil, 0);
|
|
if IsTopScrolling then
|
|
begin
|
|
rs := r;
|
|
rs.Bottom := rs.Top + FStep;
|
|
Inc(r.Top, FStep);
|
|
end
|
|
else
|
|
begin
|
|
rs := r;
|
|
rs.Top := rs.Bottom - FStep;
|
|
Dec(r.Bottom, FStep);
|
|
end;
|
|
DrawFillRect(rs);
|
|
|
|
NextTime := GetTickCount;
|
|
|
|
if (NextTime - FirstTime) > dxSideBarGroupScrollTimeToIncrement then
|
|
begin
|
|
FirstTime := NextTime;
|
|
Inc(FStep, dxSideBarGroupScrollIncrement);
|
|
end;
|
|
end;
|
|
SideBar.FOldActiveGroup := nil;
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.DoDrawItemBorder(AItemViewInfo: TdxSideItemViewInfo; const ARect: TRect);
|
|
var
|
|
ABorderRect: TRect;
|
|
begin
|
|
if AItemViewInfo.Item.Enabled then
|
|
begin
|
|
ABorderRect := ARect;
|
|
if AItemViewInfo.Item.IsSelected or SideBar.MouseFocusedItemIsDown then
|
|
DrawEdge(DC, ABorderRect, BDR_SUNKENINNER, BF_RECT)
|
|
else
|
|
DrawEdge(DC, ABorderRect, BDR_RAISEDOUTER, BF_RECT);
|
|
// if (AItemViewInfo.ItemRect.Left < AItemViewInfo.BorderRect.Left)
|
|
// or (AItemViewInfo.ItemRect.Top < AItemViewInfo.BorderRect.Top) then
|
|
begin
|
|
with ABorderRect do
|
|
begin
|
|
ExcludeClipRect(Rect(Left, Top, Left + 1, Bottom)); //[
|
|
ExcludeClipRect(Rect(Right - 1, Top, Right, Bottom)); //]
|
|
ExcludeClipRect(Rect(Left, Top, Right, Top + 1)); //-
|
|
ExcludeClipRect(Rect(Left, Bottom - 1, Right, Bottom)); //_
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.DrawFillRect(ARect: TRect);
|
|
begin
|
|
if (SideBar.BkPicture.Graphic = nil) or (SideBar.BkPicture.Graphic.Empty) then begin
|
|
if (SideBar.BkGround.IsUsed) then
|
|
DrawDifColorsOnCanvas(Canvas, SideBar.BkGround.BeginColor, SideBar.BkGround.EndColor,
|
|
SideBar.BkGround.Step, (SideBar.BkGround.FillStyle = bfsHorz), ARect, ClientWidth, ClientHeight)
|
|
else
|
|
begin
|
|
Canvas.Brush.Color := SideBar.Color;
|
|
Canvas.FillRect(ARect);
|
|
end;
|
|
end else DrawBmpOnCanvas(Canvas, SideBar.BkPicture, ARect, ClientWidth, ClientHeight);
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.DrawGroups;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
for i := 0 to ViewInfo.GroupCount - 1 do
|
|
DrawGroup(ViewInfo.Groups[i]);
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.DrawItems;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
for i := 0 to ViewInfo.ItemCount - 1 do
|
|
DrawItem(ViewInfo.Items[i]);
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.DrawGroup(AGroupViewInfo: TdxSideGroupViewInfo);
|
|
begin
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.DrawItem(AItemViewInfo: TdxSideItemViewInfo);
|
|
begin
|
|
DrawItemImage(AItemViewInfo);
|
|
DrawItemCaption(AItemViewInfo);
|
|
DrawItemBorder(AItemViewInfo);
|
|
end;
|
|
|
|
{$IFDEF DELPHI4}
|
|
const
|
|
DT_END_ELLIPSIS = $8000;
|
|
{$ENDIF}
|
|
|
|
procedure TdxSideBarPainter.DrawItemCaption(AItemViewInfo: TdxSideItemViewInfo);
|
|
var
|
|
Flag: Integer;
|
|
OldColor: TColor;
|
|
ARect: TRect;
|
|
begin
|
|
if (SideBar.ActiveGroup.IconType = dxsgLargeIcon) then
|
|
Flag := ViewInfo.GetDrawEdgeFlag
|
|
else Flag := ViewInfo.GetDrawEdgeFlag or DT_END_ELLIPSIS;
|
|
|
|
Canvas.Brush.Style := bsClear;
|
|
Canvas.Font := SideBar.ItemFont;
|
|
ARect := AItemViewInfo.CaptionRect;
|
|
|
|
DrawFillRect(ARect);
|
|
|
|
if PtInRect(ViewInfo.ItemsRect, ARect.TopLeft) then
|
|
begin
|
|
if AItemViewInfo.Item.Enabled then
|
|
cxDrawText(DC, AItemViewInfo.Caption, ARect, Flag)
|
|
else
|
|
begin
|
|
OldColor := Canvas.Font.Color;
|
|
Canvas.Font.Color := clbtnHighLight;
|
|
Canvas.Brush.Style := bsClear;
|
|
OffsetRect(ARect, 1, 1);
|
|
cxDrawText(DC, AItemViewInfo.Caption, ARect, Flag);
|
|
Canvas.Font.Color := clbtnShadow;
|
|
OffsetRect(ARect, -1, -1);
|
|
cxDrawText(DC, AItemViewInfo.Caption, ARect, Flag);
|
|
Canvas.Font.Color := OldColor;
|
|
end;
|
|
end;
|
|
ExcludeClipRect(AItemViewInfo.CaptionRect);
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.DrawImageBackground(AItemViewInfo: TdxSideItemViewInfo; ARect: TRect);
|
|
begin
|
|
DrawFillRect(ARect);
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.DrawItemImage(AItemViewInfo: TdxSideItemViewInfo);
|
|
var
|
|
ARect: TRect;
|
|
begin
|
|
ARect := AItemViewInfo.ImageRect;
|
|
DrawImageBackground(AItemViewInfo, ARect);
|
|
if IsImageAssigned(AItemViewInfo.ImageList, AItemViewInfo.ImageIndex) then
|
|
begin
|
|
AItemViewInfo.ImageList.Draw(Canvas, AItemViewInfo.ImageRect.Left, AItemViewInfo.ImageRect.Top, AItemViewInfo.ImageIndex, AItemViewInfo.Item.Enabled);
|
|
if ARect.Bottom > ViewInfo.ItemsRect.Bottom then
|
|
ARect.Bottom := ViewInfo.ItemsRect.Bottom;
|
|
ExcludeClipRect(ARect);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.DrawItemBorder(AItemViewInfo: TdxSideItemViewInfo);
|
|
begin
|
|
if IsImageAssigned(AItemViewInfo.ImageList, AItemViewInfo.ImageIndex) and
|
|
(AItemViewInfo.Item.IsFocused or AItemViewInfo.Item.IsSelected) then
|
|
DoDrawItemBorder(AItemViewInfo, AItemViewInfo.BorderRect);
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.DrawScrollButtons;
|
|
Const
|
|
ConstPushed: Array[False..True] of Integer =
|
|
(0, DFCS_PUSHED);
|
|
begin
|
|
if ViewInfo.IsTopScrollButtonVisible then
|
|
begin
|
|
DrawFrameControl(Canvas.Handle, ViewInfo.TopScrollButtonRect, DFC_SCROLL,
|
|
DFCS_SCROLLUP or ConstPushed[(dxSideBarDragObject = nil) and SideBar.FScrollButtonUpIsDown]);
|
|
ExcludeClipRect(ViewInfo.TopScrollButtonRect);
|
|
end;
|
|
if ViewInfo.IsBottomScrollButtonVisible then
|
|
begin
|
|
DrawFrameControl(Canvas.Handle, ViewInfo.BottomScrollButtonRect, DFC_SCROLL,
|
|
DFCS_SCROLLDOWN or ConstPushed[(dxSideBarDragObject = nil) and SideBar.FScrollButtonDownIsDown]);
|
|
ExcludeClipRect(ViewInfo.BottomScrollButtonRect);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarPainter.DrawDragDestinationArrow;
|
|
var
|
|
p1, p2, p3: TPoint;
|
|
r: TRect;
|
|
OldColor: TColor;
|
|
fdY: Integer;
|
|
|
|
function HasTopTriangle: Boolean;
|
|
begin
|
|
Result := (SideBar.DropItemPosition <> sbdspTop) or ((SideBar.DestDropItemViewInfo <> nil)
|
|
and (SideBar.DestDropItemViewInfo.Index > 0));
|
|
end;
|
|
|
|
function HasBottomTriangle: Boolean;
|
|
begin
|
|
Result := (SideBar.DropItemPosition <> sbdspBottom) or ((SideBar.DestDropItemViewInfo <> nil)
|
|
and (SideBar.DestDropItemViewInfo.Index + 1 < ViewInfo.ItemCount));
|
|
end;
|
|
|
|
begin
|
|
if SideBar.DropItemPosition = sbdspIn then
|
|
Exit;
|
|
if SideBar.DestDropItemViewInfo <> nil then
|
|
r := SideBar.DestDropItemViewInfo.GetItemDragSourceSpace(SideBar.DropItemPosition)
|
|
else
|
|
begin
|
|
r := ViewInfo.ItemsRect;
|
|
r.Bottom := r.Top + dxSideBarDragArrowHeight - 1;
|
|
end;
|
|
InflateRect(r, - SideBar.SpaceHeight, 0);
|
|
|
|
OldColor := Canvas.Brush.Color;
|
|
Canvas.Brush.Color := clBlack;
|
|
|
|
Canvas.MoveTo(r.Left + dxSideBarDragArrowHeight, r.Top + dxSideBarDragArrowHeight div 2);
|
|
Canvas.LineTo(r.Right - dxSideBarDragArrowHeight, r.Top + dxSideBarDragArrowHeight div 2);
|
|
|
|
p3.Y := r.Top + dxSideBarDragArrowHeight div 2;
|
|
fdY := 0;
|
|
if HasTopTriangle then
|
|
p1.Y := r.Top
|
|
else
|
|
begin
|
|
p1.Y := p3.Y;
|
|
fdY := 1;
|
|
end;
|
|
if HasBottomTriangle then
|
|
p2.Y := r.Bottom
|
|
else
|
|
begin
|
|
p2.Y := p3.Y;
|
|
fdY := -1;
|
|
end;
|
|
|
|
p3.X := r.Left + dxSideBarDragArrowHeight - 1;
|
|
p1.X := r.Left;
|
|
p2.X := r.Left;
|
|
|
|
Canvas.Polyline([p1, p2, p3, p1]);
|
|
Canvas.FloodFill(p3.X - dxSideBarDragArrowHeight div 2, p3.Y + fdy, clBlack, fsBorder);
|
|
|
|
p3.X := r.Right - dxSideBarDragArrowHeight + 1;
|
|
p1.X := r.Right;
|
|
p2.X := r.Right;
|
|
Canvas.Polyline([p1, p2, p3, p1]);
|
|
Canvas.FloodFill(p3.X + dxSideBarDragArrowHeight div 2, p3.Y+ fdy, clBlack, fsBorder);
|
|
Canvas.Brush.Color := OldColor;
|
|
end;
|
|
|
|
{TdxSideBarFlatPainter}
|
|
function TdxSideBarFlatViewInfo.GetGroupHeight: Integer;
|
|
begin
|
|
Result := SideBar.GroupHeightOffSet * 2;
|
|
if (Result = 0) then
|
|
Result := 8;
|
|
Inc(Result, GetFontHeight(SideBar.GroupFont));
|
|
end;
|
|
|
|
function TdxSideBarFlatViewInfo.GetPaintRect: TRect;
|
|
begin
|
|
if SideBar.ShowGroups then
|
|
SetRect(Result, 1, 1, SideBar.ClientWidth - 1, SideBar.ClientHeight)
|
|
else SetRect(Result, 1, 0, SideBar.ClientWidth - 1, SideBar.ClientHeight);
|
|
end;
|
|
|
|
function TdxSideBarFlatPainter.CreateViewInfo: TdxSideBarViewInfo;
|
|
begin
|
|
Result := TdxSideBarFlatViewInfo.Create(self);
|
|
end;
|
|
|
|
procedure TdxSideBarFlatPainter.DrawBorder;
|
|
var
|
|
r: TRect;
|
|
begin
|
|
SetRect(r, 0, 0, ClientWidth, ClientHeight);
|
|
DrawEdge(DC, r, BDR_SUNKENOUTER, BF_RECT);
|
|
InflateRect(r, -1, -1);
|
|
IntersectClipRect(r);
|
|
end;
|
|
|
|
procedure TdxSideBarFlatPainter.DrawGroup(AGroupViewInfo: TdxSideGroupViewInfo);
|
|
var
|
|
r, r1: TRect;
|
|
begin
|
|
Canvas.Brush.Color := clBtnFace;
|
|
Canvas.Font := SideBar.GroupFont;
|
|
r := AGroupViewInfo.Rect;
|
|
|
|
InflateRect(r, -1, -1);
|
|
r1 := r;
|
|
cxDrawText(DC, AGroupViewInfo.Caption, r1,
|
|
DT_CENTER or DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS or DT_NOPREFIX);
|
|
cxDrawText(DC, AGroupViewInfo.Caption, r1,
|
|
DT_CENTER or DT_VCENTER or DT_CALCRECT or DT_END_ELLIPSIS or DT_NOPREFIX);
|
|
if (r1.Right > r.Right) then
|
|
begin
|
|
r1.Left := r.Left;
|
|
r1.Right := r.Right;
|
|
end;
|
|
|
|
OffSetRect(r1, ((r.Right - r.Left) - (r1.Right - r1.Left)) div 2,
|
|
((r.Bottom - r.Top) - (r1.Bottom - r1.Top)) div 2);
|
|
ExcludeClipRect(r1);
|
|
Canvas.FillRect(r);
|
|
|
|
InflateRect(r, 1, 1);
|
|
if (SideBar.FMouseFocusedGroup = AGroupViewInfo.Group) then
|
|
begin
|
|
if not SideBar.FMouseFocusedGroupIsDown then
|
|
begin
|
|
DrawEdge(DC, r, BDR_RAISEDINNER, BF_TOPLEFT);
|
|
DrawEdge(DC, r, BDR_RAISEDOUTER, BF_BOTTOMRIGHT);
|
|
InflateRect(r, -1, -1);
|
|
DrawEdge(DC, r, BDR_RAISEDINNER, BF_BOTTOMRIGHT);
|
|
Dec(r.Bottom);
|
|
Dec(r.Right);
|
|
end
|
|
else
|
|
begin
|
|
DrawEdge(DC, r, BDR_SUNKENINNER, BF_TOPLEFT);
|
|
DrawEdge(DC, r, BDR_SUNKENOUTER, BF_BOTTOMRIGHT);
|
|
InflateRect(r, -1, -1);
|
|
DrawEdge(DC, r, BDR_SUNKENOUTER, BF_TOPLEFT);
|
|
Inc(r.Top);
|
|
Inc(r.Left);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
DrawEdge(DC, r, BDR_RAISEDINNER, BF_TOPLEFT);
|
|
DrawEdge(DC, r, BDR_RAISEDINNER, BF_BOTTOMRIGHT);
|
|
end;
|
|
r := AGroupViewInfo.Rect;
|
|
if AGroupViewInfo.Group.Active then
|
|
begin
|
|
Inc(r.Bottom);
|
|
DrawEdge(DC, r, BDR_RAISEDOUTER, BF_BOTTOM);
|
|
end;
|
|
ExcludeClipRect(r);
|
|
end;
|
|
|
|
function TdxSideBarFlatPainter.IsGroupFocused: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
{TStoredSideBarItemsStoreStrings}
|
|
constructor TStoredSideBarItemsStoreStrings.Create(AOwner: TdxSideBarStore);
|
|
begin
|
|
inherited Create;
|
|
Owner := AOwner;
|
|
if not (csLoading in Owner.ComponentState) then
|
|
Add(dxSideBarGetResourceString(@DXSB_DEFAULTGROUP));
|
|
end;
|
|
|
|
procedure TStoredSideBarItemsStoreStrings.ChangeCategory(OldCategory, NewCategory: Integer);
|
|
var
|
|
I: Integer;
|
|
List: TList;
|
|
begin
|
|
if (OldCategory > -1) and (OldCategory < Count)
|
|
and (NewCategory > -1) and (NewCategory < Count) then begin
|
|
List := TList.Create;
|
|
Owner.GetItemsByCategory(Strings[OldCategory], List);
|
|
for I := 0 to List.Count - 1 do
|
|
TdxStoredSideItem(List[I]).Category := NewCategory;
|
|
List.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TStoredSideBarItemsStoreStrings.Clear;
|
|
begin
|
|
if (Owner.Count > 0) and not (csLoading in Owner.ComponentState) then
|
|
raise EdxSideBarError.Create(dxSideBarGetResourceString(@DXSB_CANTDELETEGROUP))
|
|
else begin
|
|
inherited Clear;
|
|
if not (csLoading in Owner.ComponentState) then
|
|
Add(dxSideBarGetResourceString(@DXSB_DEFAULTGROUP));
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TStoredSideBarItemsStoreStrings.Delete(Index: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if (Index > -1 ) and (Index < Count) and (Owner.GetCountByCategory(Strings[Index]) > 0) then
|
|
raise EdxSideBarError.Create(dxSideBarGetResourceString(@DXSB_CANTDELETEGROUP))
|
|
else begin
|
|
if (Index > -1 ) and (Index < Count) then
|
|
for I := Index to Count - 1 do
|
|
ChangeCategory(I + 1, I);
|
|
inherited Delete(Index);
|
|
end;
|
|
if Count = 0 then
|
|
Add(dxSideBarGetResourceString(@DXSB_DEFAULTGROUP));
|
|
end;
|
|
|
|
procedure TStoredSideBarItemsStoreStrings.Insert(Index: Integer; const S: string);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
inherited Insert(Index, S);
|
|
if (Index < Count) and (Index > -1) then
|
|
for I := Count - 1 downto Index + 1 do
|
|
ChangeCategory(I - 1, I);
|
|
end;
|
|
|
|
procedure TStoredSideBarItemsStoreStrings.Exchange(Index1, Index2: Integer);
|
|
var
|
|
I: Integer;
|
|
List1: TList;
|
|
List2: TList;
|
|
begin
|
|
if (Index1 > -1) and (Index1 < Count)
|
|
and (Index2 > -1) and (Index2 < Count) then begin
|
|
List1 := TList.Create;
|
|
List2 := TList.Create;
|
|
Owner.GetItemsByCategory(Strings[Index1], List1);
|
|
Owner.GetItemsByCategory(Strings[Index2], List2);
|
|
for I := 0 to List1.Count - 1 do
|
|
TdxStoredSideItem(List1[I]).Category := Index2;
|
|
for I := 0 to List2.Count - 1 do
|
|
TdxStoredSideItem(List2[I]).Category := Index1;
|
|
List1.Free;
|
|
List2.Free;
|
|
end;
|
|
inherited Exchange(Index1, Index2);
|
|
end;
|
|
|
|
procedure TStoredSideBarItemsStoreStrings.Move(CurIndex, NewIndex: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if (CurIndex < NewIndex) then begin
|
|
for I := CurIndex + 1 to NewIndex do
|
|
ChangeCategory(I, I - 1);
|
|
end else
|
|
for I := NewIndex to CurIndex - 1 do
|
|
ChangeCategory(I, I + 1);
|
|
inherited Move(CurIndex, NewIndex);
|
|
end;
|
|
|
|
{TSideBarRenameEdit}
|
|
procedure TSideBarRenameEdit.CreateParams(var Params: TCreateParams);
|
|
begin
|
|
inherited CreateParams(Params);
|
|
Params.Style := Params.Style or WS_BORDER;
|
|
if (TdxSideBar(Owner).FRenameItem <> nil) then begin
|
|
if (TdxSideBar(Owner).ActiveGroup.IconType = dxsgLargeIcon) then
|
|
Params.Style := Params.Style or ES_MULTILINE or ES_CENTER or ES_AUTOHSCROLL
|
|
else Params.Style := Params.Style or ES_LEFT or ES_AUTOHSCROLL;
|
|
end;
|
|
end;
|
|
|
|
procedure TSideBarRenameEdit.WMChar(var Message: TWMChar);
|
|
var
|
|
ABounds: TRect;
|
|
ACurrentText: string;
|
|
begin
|
|
if (Message.CharCode = VK_RETURN) or (Message.CharCode = VK_ESCAPE) then
|
|
begin
|
|
TdxSideBar(Owner).EndEdit(Message.CharCode = VK_RETURN);
|
|
Exit;
|
|
end;
|
|
inherited;
|
|
if (TdxSideBar(Owner).FRenameItem <> nil) then begin
|
|
if (TdxSideBar(Owner).ActiveGroup.IconType = dxsgLargeIcon) then
|
|
ACurrentText := Text
|
|
else
|
|
ACurrentText := '';
|
|
ABounds:= TdxSideBar(Owner).ViewInfo.GetItemEditRect(TdxSideBar(Owner).FRenameItem,
|
|
ACurrentText);
|
|
InflateRect(ABounds, 2, 2);
|
|
if (Left <> ABounds.Left) or (Width <> ABounds.Right - ABounds.Left)
|
|
or (Height <> ABounds.Bottom - ABounds.Top) or (Top <> ABounds.Top) then
|
|
SetBounds(ABounds.Left, ABounds.Top, ABounds.Right - ABounds.Left,
|
|
ABounds.Bottom - ABounds.Top);
|
|
end;
|
|
end;
|
|
|
|
{TdxSideBarViewInfo}
|
|
constructor TdxSideBarViewInfo.Create(APainter: TdxSideBarPainter);
|
|
begin
|
|
inherited Create;
|
|
FPainter := APainter;
|
|
FGroups := TList.Create;
|
|
FItems := TList.Create;
|
|
end;
|
|
|
|
destructor TdxSideBarViewInfo.Destroy;
|
|
begin
|
|
Clear;
|
|
FGroups.Free;
|
|
FItems.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxSideBarViewInfo.Clear;
|
|
begin
|
|
ClearGroups;
|
|
ClearItems;
|
|
end;
|
|
|
|
procedure TdxSideBarViewInfo.Unready;
|
|
begin
|
|
FIsReady := False;
|
|
end;
|
|
|
|
procedure TdxSideBarViewInfo.CalcViewInfo;
|
|
begin
|
|
Clear;
|
|
CreateGroups;
|
|
CalcItemsRect;
|
|
CreateItems;
|
|
CalcScrollButtonsRect;
|
|
|
|
FIsReady := True;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.SideBar: TdxSideBar;
|
|
begin
|
|
Result := Painter.SideBar;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GroupCount: Integer;
|
|
begin
|
|
Result := FGroups.Count;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.ItemCount: Integer;
|
|
begin
|
|
Result := FItems.Count;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetGroup(Index: Integer): TdxSideGroupViewInfo;
|
|
begin
|
|
Result := TdxSideGroupViewInfo(FGroups[Index]);
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetItem(Index: Integer): TdxSideItemViewInfo;
|
|
begin
|
|
Result := TdxSideItemViewInfo(FItems[Index]);
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GroupIndexOf(AGroup: TdxSideGroupViewInfo): Integer;
|
|
begin
|
|
Result := FGroups.IndexOf(AGroup);
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.ItemIndexOf(AItem: TdxSideItemViewInfo): Integer;
|
|
begin
|
|
Result := FItems.IndexOf(AItem);
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetGroupViewInfoByGroup(AGroup: TdxSideGroup): TdxSideGroupViewInfo;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := nil;
|
|
for i := 0 to GroupCount - 1 do
|
|
if Groups[i].Group = AGroup then
|
|
begin
|
|
Result := Groups[i];
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetItemViewInfoByItem(AItem: TdxSideBarItem): TdxSideItemViewInfo;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := nil;
|
|
for i := 0 to ItemCount - 1 do
|
|
if Items[i].Item = AItem then
|
|
begin
|
|
Result := Items[i];
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.ActiveGroupViewInfo: TdxSideGroupViewInfo;
|
|
begin
|
|
Result := nil;
|
|
if (SideBar.ActiveGroup <> nil) then
|
|
Result := GetGroupViewInfoByGroup(SideBar.ActiveGroup);
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetGroupViewInfoAtPos(p: TPoint): TdxSideGroupViewInfo;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := nil;
|
|
for i := 0 to GroupCount - 1 do
|
|
if ptInRect(Groups[i].Rect, p) then
|
|
begin
|
|
Result := Groups[i];
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetGroupAtPos(p: TPoint): TdxSideGroup;
|
|
begin
|
|
Result := GetViewInfoGroup(GetGroupViewInfoAtPos(p));
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetItemViewInfoAtPos(p: TPoint): TdxSideItemViewInfo;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := nil;
|
|
for i := 0 to ItemCount - 1 do
|
|
if ptInRect(Items[i].FocusedCaptionRect, p) or ptInRect(Items[i].ItemRect, p) then
|
|
begin
|
|
Result := Items[i];
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetItemAtPos(p: TPoint): TdxSideBarItem;
|
|
begin
|
|
Result := GetViewInfoItem(GetItemViewInfoAtPos(p));
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetNearestItemViewInfoAtPost(p: TPoint; var APosition: TdxSideBarDragSourcePosition): TdxSideItemViewInfo;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
APosition := sbdspIn;
|
|
if not PtInRect(ItemsRect, p) then
|
|
exit;
|
|
if ItemCount > 0 then
|
|
APosition := sbdspBottom
|
|
else APosition := sbdspTop;
|
|
for i := 0 to ItemCount - 1 do
|
|
begin
|
|
Result := Items[i];
|
|
if (p.Y <= Result.Bottom) then
|
|
begin
|
|
if p.Y < Result.Top then
|
|
APosition := sbdspTop
|
|
else APosition := sbdspIn;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetNearestItemAtPost(p: TPoint; var APosition: TdxSideBarDragSourcePosition): TdxSideBarItem;
|
|
begin
|
|
Result := GetViewInfoItem(GetNearestItemViewInfoAtPost(p, APosition));
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.IsTopScrollButtonVisible: Boolean;
|
|
begin
|
|
Result := FTopScrollButtonRect.Left < FTopScrollButtonRect.Right;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.IsBottomScrollButtonVisible: Boolean;
|
|
begin
|
|
Result := FBottomScrollButtonRect.Left < FBottomScrollButtonRect.Right;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.IsPtTopScrollButton(pt: TPoint): Boolean;
|
|
begin
|
|
Result := PtInRect(FTopScrollButtonRect, pt);
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.IsPtBottomScrollButton(pt: TPoint): Boolean;
|
|
begin
|
|
Result := PtInRect(FBottomScrollButtonRect, pt);
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.CreateGroup(AGroup: TdxSideGroup; ARect: TRect): TdxSideGroupViewInfo;
|
|
begin
|
|
Result := TdxSideGroupViewInfo.Create(self, AGroup, ARect);
|
|
end;
|
|
|
|
procedure TdxSideBarViewInfo.CreateGroups;
|
|
var
|
|
i: Integer;
|
|
APaintRect: TRect;
|
|
AGroupHeight: Integer;
|
|
ATop_Bottom: Integer;
|
|
AMaxGroupIndex: Integer;
|
|
ABottomHeight: Integer;
|
|
begin
|
|
if (not SideBar.ShowGroups or (SideBar.ActiveGroup = nil)) then exit;
|
|
|
|
APaintRect := GetPaintRect;
|
|
AGroupHeight := GetGroupHeight;
|
|
|
|
Painter.Canvas.Font := SideBar.GroupFont;
|
|
|
|
ATop_Bottom := APaintRect.Top;
|
|
for i := 0 to SideBar.ActiveGroup.Index do
|
|
if (SideBar.Groups[i].Visible) then
|
|
begin
|
|
FGroups.Add(CreateGroup(SideBar.Groups[i], Rect(APaintRect.Left, ATop_Bottom,
|
|
APaintRect.Right, ATop_Bottom + AGroupHeight)));
|
|
Inc(ATop_Bottom, AGroupHeight + GetGroupOffSet);
|
|
end;
|
|
|
|
Inc(ATop_Bottom, Sidebar.SpaceHeight + AGroupHeight + GetGroupOffSet);
|
|
ABottomHeight := 0;
|
|
for i := SideBar.ActiveGroup.Index + 1 to SideBar.GroupCount - 1 do
|
|
begin
|
|
if(ATop_Bottom > APaintRect.Bottom) then break;
|
|
if (SideBar.Groups[i].Visible) then
|
|
begin
|
|
Inc(ATop_Bottom, AGroupHeight + GetGroupOffSet);
|
|
Inc(ABottomHeight, AGroupHeight + GetGroupOffSet);
|
|
end;
|
|
end;
|
|
|
|
AMaxGroupIndex := SideBar.GroupCount - 1;
|
|
ATop_Bottom := APaintRect.Bottom - ABottomHeight;
|
|
for i := SideBar.ActiveGroup.Index + 1 to AMaxGroupIndex do
|
|
if (SideBar.Groups[i].Visible) then
|
|
begin
|
|
FGroups.Add(CreateGroup(SideBar.Groups[i], Rect(APaintRect.Left, ATop_Bottom,
|
|
APaintRect.Right, ATop_Bottom + AGroupHeight)));
|
|
Inc(ATop_Bottom, AGroupHeight + GetGroupOffSet);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarViewInfo.ClearGroups;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
for i := 0 to GroupCount - 1 do
|
|
Groups[i].Free;
|
|
FGroups.Clear;
|
|
end;
|
|
|
|
procedure TdxSideBarViewInfo.CalcItemsRect;
|
|
var
|
|
AGroupViewInfo: TdxSideGroupViewInfo;
|
|
begin
|
|
FItemsRect := GetPaintRect;
|
|
InflateRect(FItemsRect, -1, -1);
|
|
AGroupViewInfo := ActiveGroupViewInfo;
|
|
if AGroupViewInfo <> nil then
|
|
begin
|
|
FItemsRect.Top := AGroupViewInfo.Rect.Bottom;
|
|
if AGroupViewInfo.Index + 1 < GroupCount then
|
|
begin
|
|
AGroupViewInfo := Groups[AGroupViewInfo.Index + 1];
|
|
FItemsRect.Bottom := AGroupViewInfo.Rect.Top;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideBarViewInfo.CalcScrollButtonsRect;
|
|
begin
|
|
SetRectEmpty(FTopScrollButtonRect);
|
|
SetRectEmpty(FBottomScrollButtonRect);
|
|
|
|
if (ItemCount = 0) then
|
|
Exit;
|
|
|
|
if Items[0].Item.Index > 0 then
|
|
begin
|
|
FTopScrollButtonRect := ItemsRect;
|
|
FTopScrollButtonRect.Left := FTopScrollButtonRect.Right - ScrollButtonHeight;
|
|
FTopScrollButtonRect.Bottom := FTopScrollButtonRect.Top + ScrollButtonHeight;
|
|
OffSetRect(FTopScrollButtonRect, - SideBar.SpaceHeight, SideBar.SpaceHeight);
|
|
end;
|
|
if (Items[ItemCount - 1].Item.Index + 1 < SideBar.ActiveGroup.ItemCount)
|
|
or (Items[ItemCount - 1].IsPartialVisible) then
|
|
begin
|
|
FBottomScrollButtonRect := ItemsRect;
|
|
FBottomScrollButtonRect.Left := FBottomScrollButtonRect.Right - ScrollButtonHeight;
|
|
FBottomScrollButtonRect.Top := FBottomScrollButtonRect.Bottom - ScrollButtonHeight;
|
|
OffSetRect(FBottomScrollButtonRect, - SideBar.SpaceHeight, - SideBar.SpaceHeight);
|
|
end;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.CreateItemInfo(AItem: TdxSideBarItem; AImageRect, ACaptionRect: TRect): TdxSideItemViewInfo;
|
|
begin
|
|
Result := TdxSideItemViewInfo.Create(self, AItem, AImageRect, ACaptionRect);
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.CreateItem(AItem: TdxSideBarItem; ATop: Integer): TdxSideItemViewInfo;
|
|
var
|
|
ACaptionRect, AImageRect: TRect;
|
|
begin
|
|
AImageRect := GetItemImageRect(AItem, ATop);
|
|
ACaptionRect := GetItemCaptionRect(AItem, ATop, AImageRect);
|
|
Result := CreateItemInfo(AItem, AImageRect, ACaptionRect);
|
|
end;
|
|
|
|
procedure TdxSideBarViewInfo.CreateItems;
|
|
var
|
|
ATop: Integer;
|
|
AItemViewInfo: TdxSideItemViewInfo;
|
|
i: Integer;
|
|
begin
|
|
if (SideBar.ActiveGroup = nil) then exit;
|
|
Painter.Canvas.Font.Assign(SideBar.ItemFont);
|
|
ATop := ItemsRect.Top;
|
|
for i := SideBar.ActiveGroup.TopVisibleItem to SideBar.ActiveGroup.ItemCount - 1 do
|
|
begin
|
|
Inc(ATop, GetSideBarTopItemSpaceHeight);
|
|
if ATop >= ItemsRect.Bottom then
|
|
break;
|
|
AItemViewInfo := CreateItem(SideBar.ActiveGroup.Items[i], ATop);
|
|
ATop := AItemViewInfo.Bottom;
|
|
FItems.Add(AItemViewInfo);
|
|
end;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetSideBarTopItemSpaceHeight: Integer;
|
|
begin
|
|
Result := SideBar.SpaceHeight;
|
|
end;
|
|
|
|
procedure TdxSideBarViewInfo.ClearItems;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
for i := 0 to ItemCount - 1 do
|
|
Items[i].Free;
|
|
FItems.Clear;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetGroupHeight: Integer;
|
|
begin
|
|
Result := SideBar.GroupHeightOffSet * 2;
|
|
if (Result = 0) then
|
|
Result := 4;
|
|
Inc(Result, GetFontHeight(SideBar.GroupFont));
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetPaintRect: TRect;
|
|
begin
|
|
Result := SideBar.ClientRect;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetGroupOffSet: Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetBorderOffSet: Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetItemViewInfo(AItem: TdxSideBarItem): TdxSideItemViewInfo;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
for I := 0 to ItemCount - 1 do
|
|
if Items[I].Item = AItem then
|
|
begin
|
|
Result := Items[I];
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetItemImageRect(AItem: TdxSideBarItem; ATop: Integer): TRect;
|
|
begin
|
|
with GetPaintRect do
|
|
SetRect(Result, Left, SideBar.SpaceHeight, Right, Bottom);
|
|
if (SideBar.ActiveGroup.IconType = dxsgLargeIcon) then begin
|
|
Result.Bottom := Result.Top + GetLargeImageHeight;
|
|
Inc(Result.Left, (Result.Right - Result.Left - GetLargeImageWidth) div 2);
|
|
Result.Right := Result.Left + GetLargeImageWidth;
|
|
end
|
|
else
|
|
begin
|
|
Inc(Result.Left, SideBar.SpaceHeight);
|
|
Result.Right := Result.Left + GetSmallImageWidth;
|
|
if GetItemHeight > GetSmallImageHeight then
|
|
Inc(Result.Top, (GetItemHeight - GetSmallImageHeight) div 2);
|
|
Result.Bottom := Result.Top + GetSmallImageHeight
|
|
end;
|
|
OffSetRect(Result, 0, ATop);
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetItemCorrectedCaptionRect(ACaption: String; ARect: TRect): TRect;
|
|
var
|
|
AHeight: Integer;
|
|
begin
|
|
Result := ARect;
|
|
AHeight := cxDrawText(Painter.DC, ACaption, Result, GetDrawEdgeFlag or DT_CALCRECT);
|
|
if (SideBar.ActiveGroup.IconType = dxsgLargeIcon) then
|
|
begin
|
|
OffSetRect(Result, ((ItemsRect.Right - ItemsRect.Left) - (Result.Right - Result.Left)) div 2, 0);
|
|
Result.Bottom := Result.Top + AHeight;
|
|
end else
|
|
begin
|
|
if Result.Right > ItemsRect.Right - SideBar.SpaceHeight then
|
|
Result.Right := ItemsRect.Right - SideBar.SpaceHeight;
|
|
end;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetItemCaptionRect(AItem: TdxSideBarItem; ATop: Integer; AImageRect: TRect): TRect;
|
|
begin
|
|
if (SideBar.ActiveGroup.IconType = dxsgLargeIcon) then
|
|
begin
|
|
Result := ItemsRect;
|
|
Result.Top := AImageRect.Bottom + SideBar.SpaceHeight;
|
|
end
|
|
else
|
|
begin
|
|
Result.Top := ATop + SideBar.SpaceHeight;
|
|
if (GetItemHeight < GetSmallImageHeight) then
|
|
Inc(Result.Top, (GetSmallImageHeight - GetItemHeight) div 2);
|
|
Result.Bottom := Result.Top + GetItemHeight;
|
|
Result.Left := AImageRect.Right + SideBar.SpaceHeight;
|
|
Result.Right := SideBar.ClientWidth - Result.Top - SideBar.SpaceHeight;
|
|
end;
|
|
Result := GetItemCorrectedCaptionRect(AItem.Caption, Result);
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetItemEditRect(AItem: TdxSideBarItem; ACaption: String): TRect;
|
|
var
|
|
AItemViewInfo: TdxSideItemViewInfo;
|
|
begin
|
|
AItemViewInfo := GetItemViewInfoByItem(AItem);
|
|
if AItemViewInfo = nil then
|
|
begin
|
|
SetRectEmpty(Result);
|
|
exit;
|
|
end;
|
|
if (SideBar.ActiveGroup.IconType = dxsgLargeIcon) then
|
|
begin
|
|
Result := ItemsRect;
|
|
Result.Top := AItemViewInfo.ImageRect.Bottom + SideBar.SpaceHeight;
|
|
end
|
|
else
|
|
begin
|
|
Result := AItemViewInfo.CaptionRect;
|
|
Result.Right := ItemsRect.Right;
|
|
end;
|
|
if SideBar.Canvas.TextWidth(AItem.Caption) > SideBar.Canvas.TextWidth(ACaption) then
|
|
ACaption := AItem.Caption;
|
|
Result := GetItemCorrectedCaptionRect(ACaption, Result);
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetDrawEdgeFlag: Integer;
|
|
begin
|
|
if (SideBar.ActiveGroup.IconType = dxsgLargeIcon) then
|
|
Result := DT_CENTER or DT_WORDBREAK or DT_EDITCONTROL
|
|
else Result := DT_LEFT or DT_VCENTER or DT_SINGLELINE;
|
|
Result := Result or DT_NOPREFIX;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetItemHeight: Integer;
|
|
begin
|
|
Result := GetFontHeight(SideBar.ItemFont) + 2;
|
|
if (GetSmallImageHeight > Result) then
|
|
Result := GetSmallImageHeight;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetLargeImageHeight: Integer;
|
|
begin
|
|
if (SideBar.GetLargeImages <> nil) then
|
|
Result := SideBar.GetLargeImages.Height
|
|
else Result := dxSideBarDefaultLargeImageHeight;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetLargeImageWidth: Integer;
|
|
begin
|
|
if (SideBar.GetLargeImages <> nil) then
|
|
Result := SideBar.GetLargeImages.Width
|
|
else Result := dxSideBarDefaultLargeImageWidth;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetSmallImageHeight: Integer;
|
|
begin
|
|
if (SideBar.GetSmallImages <> nil) then
|
|
Result := SideBar.GetSmallImages.Height
|
|
else Result := dxSideBarDefaultSmallImageHeight;
|
|
end;
|
|
|
|
function TdxSideBarViewInfo.GetSmallImageWidth: Integer;
|
|
begin
|
|
if (SideBar.GetSmallImages <> nil) then
|
|
Result := SideBar.GetSmallImages.Width
|
|
else Result := dxSideBarDefaultSmallImageWidth;
|
|
end;
|
|
|
|
|
|
{TdxSideGroup}
|
|
constructor TdxSideGroup.Create(Collection: TCollection);
|
|
begin
|
|
inherited Create(Collection);
|
|
FItems := TdxSideBarItems.Create(Self);
|
|
FCaption := dxSideBarGetResourceString(@DXSB_DEFAULTGROUPCAPTION);
|
|
FTopVisibleItem := 0;
|
|
FIconType := dxsgLargeIcon;
|
|
FIsAssigning := False;
|
|
FVisible := True;
|
|
if not (csLoading in SideBar.ComponentState) then
|
|
begin
|
|
if (SideBar.FActiveGroup = nil) then
|
|
SideBar.ActiveGroup := Self;
|
|
SideBar.RepaintAll;
|
|
end;
|
|
end;
|
|
|
|
destructor TdxSideGroup.Destroy;
|
|
var
|
|
Bar: TdxSideBar;
|
|
IsGroupActive: Boolean;
|
|
begin
|
|
FDestroying := True;
|
|
Bar := SideBar;
|
|
IsGroupActive := Active;
|
|
if Bar <> nil then
|
|
begin
|
|
if Bar.FMouseFocusedGroup = Self then
|
|
Bar.FMouseFocusedGroup := nil;
|
|
if Bar.FOldActiveGroup = Self then
|
|
Bar.FOldActiveGroup := nil;
|
|
if Bar.IsEditing then
|
|
Bar.EndEdit(False);
|
|
end;
|
|
FItems.Free;
|
|
FItems := nil;
|
|
inherited Destroy;
|
|
if (Bar <> nil) and not Bar.FDestroying then
|
|
begin
|
|
if IsGroupActive then
|
|
Bar.ActiveGroup := nil;
|
|
if Bar.ActiveGroup <> nil then
|
|
Bar.FActiveGroupIndex := Bar.GetVisibleIndexByGroup(Bar.ActiveGroup);
|
|
Bar.RepaintAll;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideGroup.MakeActive;
|
|
begin
|
|
SideBar.ActiveGroup := Self;
|
|
end;
|
|
|
|
function TdxSideGroup.GetActive: Boolean;
|
|
begin
|
|
Result := SideBar.ActiveGroup = Self;
|
|
end;
|
|
|
|
function TdxSideGroup.GetItemCount: Integer;
|
|
begin
|
|
if FItems = nil then
|
|
Result := 0
|
|
else Result := FItems.Count;
|
|
end;
|
|
|
|
function TdxSideGroup.SideBar: TdxSideBar;
|
|
begin
|
|
Result := TdxSideGroups(Collection).SideBar;
|
|
end;
|
|
|
|
function TdxSideGroup.GetVisibleCount: Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := 0;
|
|
if (Active) and (FTopVisibleItem > -1) and (Items.Count > 0) then
|
|
begin
|
|
I := FTopVisibleItem;
|
|
while (I < Items.Count) and Items[I].Visible do
|
|
begin
|
|
Inc(I);
|
|
Inc(Result);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideGroup.SetCaption(Value: string);
|
|
var
|
|
ABar: TdxSideBar;
|
|
begin
|
|
if (FCaption <> Value) then
|
|
begin
|
|
FCaption := Value;
|
|
if FIsAssigning then Exit;
|
|
|
|
ABar := SideBar;
|
|
if (ABar <> nil) and (([csLoading, csDestroying] * ABar.ComponentState) = []) then
|
|
begin
|
|
if Assigned(ABar.OnChangeGroupCaption) then
|
|
ABar.OnChangeGroupCaption(Self, Self);
|
|
ABar.InvalidateGroup(Self);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideGroup.SetIconType(Value: TdxSideGroupIconType);
|
|
begin
|
|
if (FIconType <> Value) then begin
|
|
FIconType := Value;
|
|
if (TopVisibleItem <> 0) then
|
|
TopVisibleItem := 0;
|
|
if FIsAssigning then Exit;
|
|
if (SideBar <> nil) and not (csLoading in SideBar.ComponentState)
|
|
and (Self = SideBar.ActiveGroup) then
|
|
SideBar.InvalidateItems(True);;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideGroup.SetItems(Value: TdxSideBarItems);
|
|
begin
|
|
FTopVisibleItem := 0;
|
|
FItems.Assign(Value);
|
|
if (FItems.Count > 0) then
|
|
FTopVisibleItem := 0;
|
|
end;
|
|
|
|
procedure TdxSideGroup.SetTopVisibleItem(Value: Integer);
|
|
begin
|
|
if (FTopVisibleItem <> Value)
|
|
and (Value > -1) and (Value < Items.Count) then begin
|
|
FTopVisibleItem := Value;
|
|
if (SideBar <> nil) and not (csLoading in SideBar.ComponentState)
|
|
and (SideBar.ActiveGroup = Self) then
|
|
SideBar.InvalidateItems(True);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideGroup.SetVisible(Value: Boolean);
|
|
begin
|
|
if (FVisible <> Value) then
|
|
begin
|
|
FVisible := Value;
|
|
if (SideBar <> nil) and not (csLoading in SideBar.ComponentState) then
|
|
SideBar.RepaintAll;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxSideGroup.Assign(Source: TPersistent);
|
|
begin
|
|
if (Source is TdxSideGroup) then begin
|
|
FIsAssigning := True;
|
|
Caption := TdxSideGroup(Source).Caption;
|
|
IconType := TdxSideGroup(Source).IconType;
|
|
Visible := TdxSideGroup(Source).Visible;
|
|
SetItems(TdxSideGroup(Source).Items);
|
|
FIsAssigning := False;
|
|
end
|
|
else inherited Assign(Source);
|
|
end;
|
|
|
|
{$IFDEF DELPHI4}
|
|
{TdxSideBarItemActionLink}
|
|
procedure TdxSideBarItemActionLink.AssignClient(AClient: TObject);
|
|
begin
|
|
FClient := AClient as TdxStoredSideItem;
|
|
end;
|
|
|
|
function TdxSideBarItemActionLink.IsCaptionLinked: Boolean;
|
|
begin
|
|
Result := inherited IsCaptionLinked and
|
|
(FClient.Caption = (Action as TCustomAction).Caption);
|
|
end;
|
|
|
|
function TdxSideBarItemActionLink.IsEnabledLinked: Boolean;
|
|
begin
|
|
Result := inherited IsEnabledLinked and
|
|
(FClient.Enabled = (Action as TCustomAction).Enabled);
|
|
end;
|
|
|
|
function TdxSideBarItemActionLink.IsHintLinked: Boolean;
|
|
begin
|
|
Result := inherited IsHintLinked and
|
|
(FClient.Hint = (Action as TCustomAction).Hint);
|
|
end;
|
|
|
|
function TdxSideBarItemActionLink.IsImageIndexLinked: Boolean;
|
|
begin
|
|
Result := inherited IsImageIndexLinked and
|
|
(FClient.LargeImage = (Action as TCustomAction).ImageIndex);
|
|
end;
|
|
|
|
procedure TdxSideBarItemActionLink.SetCaption(const Value: string);
|
|
begin
|
|
if IsCaptionLinked then FClient.Caption := Value;
|
|
end;
|
|
|
|
procedure TdxSideBarItemActionLink.SetEnabled(Value: Boolean);
|
|
begin
|
|
if IsEnabledLinked then FClient.Enabled := Value;
|
|
end;
|
|
|
|
procedure TdxSideBarItemActionLink.SetHint(const Value: string);
|
|
begin
|
|
if IsHintLinked then FClient.Hint := Value;
|
|
end;
|
|
|
|
procedure TdxSideBarItemActionLink.SetImageIndex(Value: Integer);
|
|
begin
|
|
if IsImageIndexLinked then FClient.LargeImage := Value;
|
|
end;
|
|
|
|
procedure TdxSideBarItemActionLink.SetVisible(Value: Boolean);
|
|
begin
|
|
FClient.Enabled := Value and inherited IsEnabledLinked and TCustomAction(FClient.Action).Enabled;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{TdxSideGroupViewInfo}
|
|
constructor TdxSideGroupViewInfo.Create(AViewInfo: TdxSideBarViewInfo; AGroup: TdxSideGroup; ARect: TRect);
|
|
begin
|
|
inherited Create;
|
|
FViewInfo := AViewInfo;
|
|
FGroup := AGroup;
|
|
FRect := ARect;
|
|
end;
|
|
|
|
function TdxSideGroupViewInfo.GetPainter: TdxSideBarPainter;
|
|
begin
|
|
Result := ViewInfo.Painter;
|
|
end;
|
|
|
|
function TdxSideGroupViewInfo.Index: Integer;
|
|
begin
|
|
Result := ViewInfo.GroupIndexOf(self);
|
|
end;
|
|
|
|
function TdxSideGroupViewInfo.GetCaption: String;
|
|
begin
|
|
Result := GetClippedString(Painter.DC, Group.Caption, Rect);
|
|
end;
|
|
|
|
{TdxSideGroups}
|
|
constructor TdxSideGroups.Create(AOwner: TdxSideBar);
|
|
begin
|
|
inherited Create(TdxSideGroup);
|
|
SideBar := AOwner;
|
|
end;
|
|
|
|
function TdxSideGroups.Add: TdxSideGroup;
|
|
begin
|
|
Result := TdxSideGroup(inherited Add);
|
|
end;
|
|
|
|
function TdxSideGroups.GetItem(Index: Integer): TdxSideGroup;
|
|
begin
|
|
Result := TdxSideGroup(inherited Items[Index]);
|
|
end;
|
|
|
|
function TdxSideGroups.GetVisibleItem(Index: Integer): TdxSideGroup;
|
|
var
|
|
I: Integer;
|
|
j: Integer;
|
|
begin
|
|
Result := nil;
|
|
j := 0;
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
if (Items[I].Visible) then
|
|
begin
|
|
if (Index = j) then
|
|
Result := Items[I];
|
|
Inc(j);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TdxSideGroups.GetVisibleCount: Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := 0;
|
|
for I := 0 to Count - 1 do
|
|
if (Items[I].Visible) then
|
|
Inc(Result);
|
|
end;
|
|
|
|
procedure TdxSideGroups.SetItem(Index: Integer; Value: TdxSideGroup);
|
|
begin
|
|
Items[Index].Assign(Value);
|
|
end;
|
|
|
|
procedure TdxSideGroups.Update(Item: TCollectionItem);
|
|
begin
|
|
if (SideBar <> nil) and (SideBar.Owner <> nil)
|
|
and not (csLoading in SideBar.Owner.ComponentState)
|
|
and not (csDestroying in SideBar.ComponentState)
|
|
and (Count > 0) then begin
|
|
if (SideBar.FActiveGroup = nil) or (SideBar.FActiveGroup.FDestroying) then
|
|
SideBar.ActiveGroup := Items[0]
|
|
else SideBar.RepaintAll;
|
|
end;
|
|
end;
|
|
|
|
{TdxSideBarStandardPainter}
|
|
function TdxSideBarStandardViewInfo.GetPaintRect: TRect;
|
|
var
|
|
dxy: Integer;
|
|
begin
|
|
Result := SideBar.ClientRect;
|
|
if SideBar.ShowGroups then
|
|
begin
|
|
dxy := SideBar.BevelWidth;
|
|
if (SideBar.BorderStyle = bsSingle) then
|
|
Inc(dxy, SideBar.BorderWidth);
|
|
InflateRect(Result, - dxy, - dxy);
|
|
Inc(Result.Top, 1);
|
|
Inc(Result.Bottom, 1);
|
|
end;
|
|
end;
|
|
|
|
function TdxSideBarStandardPainter.CreateViewInfo: TdxSideBarViewInfo;
|
|
begin
|
|
Result := TdxSideBarStandardViewInfo.Create(self);
|
|
end;
|
|
|
|
procedure TdxSideBarStandardPainter.DrawGroup(AGroupViewInfo: TdxSideGroupViewInfo);
|
|
var
|
|
r: TRect;
|
|
DrawCaption: string;
|
|
begin
|
|
Canvas.Font := SideBar.GroupFont;
|
|
Canvas.Brush.Color := clBtnFace;
|
|
r := DrawButtonFace(Canvas, AGroupViewInfo.Rect, 1, bsNew, True, False, False);
|
|
DrawCaption := GetClippedString(DC, AGroupViewInfo.Caption, r);
|
|
cxDrawText(DC, DrawCaption, r, DT_CENTER or DT_VCENTER
|
|
or DT_SINGLELINE or DT_END_ELLIPSIS or DT_NOPREFIX);
|
|
ExcludeClipRect(AGroupViewInfo.Rect);
|
|
end;
|
|
|
|
initialization
|
|
Classes.RegisterClass(TdxStoredSideItem);
|
|
dxSideBarDragObject := nil;
|
|
Screen.Cursors[dxSideBarDragCursor] := LoadCursor(HInstance, 'dxSideBarDragCursor');
|
|
Screen.Cursors[dxSideBarDragCopyCursor] := LoadCursor(HInstance, 'dxSideBarDragCopyCursor');
|
|
Screen.Cursors[dxSideBarDragDeleteCursor] := LoadCursor(HInstance, 'dxSideBarDragDeleteCursor');
|
|
Screen.Cursors[dxSideBarGroupCursor] := LoadCursor(HInstance, 'DXSIDEBARGROUPCURSOR');
|
|
|
|
finalization
|
|
DestroyCursor(Screen.Cursors[dxSideBarGroupCursor]);
|
|
DestroyCursor(Screen.Cursors[dxSideBarDragDeleteCursor]);
|
|
DestroyCursor(Screen.Cursors[dxSideBarDragCopyCursor]);
|
|
DestroyCursor(Screen.Cursors[dxSideBarDragCursor]);
|
|
|
|
end.
|