{*******************************************************************} { } { 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.