3272 lines
89 KiB
ObjectPascal
3272 lines
89 KiB
ObjectPascal
{-----------------------------------------------------------------------------
|
|
The contents of this file are subject to the Mozilla Public License
|
|
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
http://www.mozilla.org/MPL/MPL-1.1.html
|
|
|
|
Software distributed under the License is distributed on an "AS IS" basis,
|
|
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
|
|
the specific language governing rights and limitations under the License.
|
|
|
|
The Original Code is: JvSpeedBar.PAS, released on 2002-07-04.
|
|
|
|
The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev
|
|
Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev
|
|
Copyright (c) 2001,2002 SGB Software
|
|
All Rights Reserved.
|
|
|
|
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
|
|
located at http://jvcl.sourceforge.net
|
|
|
|
Known Issues:
|
|
-----------------------------------------------------------------------------}
|
|
// $Id: JvSpeedbar.pas,v 1.57 2005/10/28 08:37:23 marquardt Exp $
|
|
|
|
unit JvSpeedbar;
|
|
|
|
{$I jvcl.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF UNITVERSIONING}
|
|
JclUnitVersioning,
|
|
{$ENDIF UNITVERSIONING}
|
|
SysUtils, Classes, IniFiles,
|
|
Windows, Messages, Menus, Buttons, Controls,
|
|
Graphics, Forms, ImgList, ActnList, ExtCtrls, Grids,
|
|
{$IFDEF HAS_UNIT_RTLCONSTS}
|
|
RTLConsts,
|
|
{$ENDIF HAS_UNIT_RTLCONSTS}
|
|
JvVCL5Utils,
|
|
JvSpeedButton, JvAppStorage, JvConsts, JvTypes, JvFormPlacement,
|
|
JvComponent, JvThemes, JvExControls;
|
|
|
|
const
|
|
DefButtonWidth = 24;
|
|
DefButtonHeight = 23;
|
|
|
|
type
|
|
TJvSpeedItem = class;
|
|
TJvSpeedBarSection = class;
|
|
EJvSpeedbarError = class(EJVCLException);
|
|
|
|
TBarOrientation = (boHorizontal, boVertical);
|
|
TBarPosition = (bpAuto, bpCustom);
|
|
TJvSpeedBarOption = (sbAllowDrag, sbAllowResize, sbFlatBtns, sbGrayedBtns,
|
|
sbTransparentBtns, sbStretchBitmap);
|
|
TJvSpeedBarOptions = set of TJvSpeedBarOption;
|
|
TBoundLine = (blTop, blBottom, blLeft, blRight);
|
|
TBoundLines = set of TBoundLine;
|
|
TSbScaleFlags = set of (sfOffsetX, sfOffsetY, sfBtnSizeX, sfBtnSizeY);
|
|
TForEachItem = procedure(Item: TJvSpeedItem; Data: Longint) of object;
|
|
TApplyAlignEvent = procedure(Sender: TObject; Align: TAlign;
|
|
var Apply: Boolean) of object;
|
|
|
|
TJvSpeedBar = class(TJvCustomPanel, IJvDenySubClassing)
|
|
private
|
|
FSections: TList;
|
|
FPosition: TBarPosition;
|
|
FOrientation: TBarOrientation;
|
|
FAlign: TAlign;
|
|
FButtonSize: TPoint;
|
|
FButtonStyle: TButtonStyle;
|
|
FGridSize: TPoint;
|
|
FOffset: TPoint;
|
|
FEditWin: THandle;
|
|
FRowCount: Integer;
|
|
FPrevRect: TRect;
|
|
FPrevAlign: TAlign;
|
|
FOptions: TJvSpeedBarOptions;
|
|
FLocked: Boolean;
|
|
FVersion: Integer;
|
|
FDrag: Boolean;
|
|
FResizing: Boolean;
|
|
FStartDrag: TPoint;
|
|
FWallpaper: TPicture;
|
|
FBoundLines: TBoundLines;
|
|
FIniLink: TJvIniLink;
|
|
FReserved: Integer;
|
|
FFix: Boolean;
|
|
FDesignStyle: Boolean;
|
|
FScaleFlags: TSbScaleFlags;
|
|
FOnAddItem: TNotifyEvent;
|
|
FOnApplyAlign: TApplyAlignEvent;
|
|
FOnPosChanged: TNotifyEvent;
|
|
FOnVisibleChanged: TNotifyEvent;
|
|
FOnCustomize: TNotifyEvent;
|
|
FImages: TCustomImageList;
|
|
FImageChangeLink: TChangeLink;
|
|
procedure ImageListChange(Sender: TObject);
|
|
procedure SetImages(Value: TCustomImageList);
|
|
procedure InvalidateItem(Item: TJvSpeedItem; Data: Longint);
|
|
function GetOrientation: TBarOrientation;
|
|
procedure SetOrientation(Value: TBarOrientation);
|
|
procedure ApplyOrientation(Value: TBarOrientation);
|
|
procedure ApplyButtonSize;
|
|
procedure UpdateGridSize;
|
|
procedure ClearSections;
|
|
function GetAlign: TAlign;
|
|
procedure SetAlign(Value: TAlign);
|
|
function GetButtonSize(Index: Integer): Integer;
|
|
procedure SetButtonSize(Index, Value: Integer);
|
|
function GetButtonsOffset(Index: Integer): Integer;
|
|
procedure SetButtonsOffset(Index: Integer; Value: Integer);
|
|
procedure SetOptions(Value: TJvSpeedBarOptions);
|
|
procedure SetBoundLines(Value: TBoundLines);
|
|
function MinButtonsOffset: Integer;
|
|
procedure WallpaperChanged(Sender: TObject);
|
|
procedure SetWallpaper(Value: TPicture);
|
|
procedure SetItemParams(Item: TJvSpeedItem; InitBounds: Boolean);
|
|
procedure SetItemVisible(Item: TJvSpeedItem; Data: Longint);
|
|
procedure SetItemEnabled(Item: TJvSpeedItem; Data: Longint);
|
|
procedure SetItemButtonSize(Item: TJvSpeedItem; Data: Longint);
|
|
procedure OffsetItem(Item: TJvSpeedItem; Data: Longint);
|
|
procedure ApplyItemSize(Item: TJvSpeedItem; Data: Longint);
|
|
procedure AlignItemToGrid(Item: TJvSpeedItem; Data: Longint);
|
|
procedure SwapItemBounds(Item: TJvSpeedItem; Data: Longint);
|
|
procedure SetItemEditing(Item: TJvSpeedItem; Data: Longint);
|
|
procedure HideItem(Item: TJvSpeedItem; Data: Longint);
|
|
procedure WriteItemLayout(Item: TJvSpeedItem; Data: Longint);
|
|
procedure FlatItem(Item: TJvSpeedItem; Data: Longint);
|
|
procedure TransparentItem(Item: TJvSpeedItem; Data: Longint);
|
|
function GetSection(Index: Integer): TJvSpeedBarSection;
|
|
function GetSectionCount: Integer;
|
|
procedure GrayedItem(Item: TJvSpeedItem; Data: Longint);
|
|
function GetFramePos(X, Y: Integer; var Apply: Boolean): Integer;
|
|
function GetFrameRect(X, Y: Integer): TRect;
|
|
procedure StartDragFrame;
|
|
procedure DragFrame(X, Y: Integer);
|
|
procedure StopDragFrame(X, Y: Integer);
|
|
function CheckResize(Shift: TShiftState; X, Y: Integer): Boolean;
|
|
procedure ReadSections(Reader: TReader);
|
|
procedure WriteSections(Writer: TWriter);
|
|
procedure ReadData(Reader: TReader);
|
|
procedure WriteData(Writer: TWriter);
|
|
procedure ReadDesignStyle(Reader: TReader);
|
|
procedure ReadAllowDrag(Reader: TReader);
|
|
procedure WriteDesignStyle(Writer: TWriter);
|
|
function GetStorage: TJvFormPlacement;
|
|
procedure SetStorage(Value: TJvFormPlacement);
|
|
procedure IniSave(Sender: TObject);
|
|
procedure IniLoad(Sender: TObject);
|
|
protected
|
|
procedure VisibleChanged; override;
|
|
procedure EnabledChanged; override;
|
|
procedure AlignControls(AControl: TControl; var Rect: TRect); override;
|
|
function AppendSection(Value: TJvSpeedBarSection): Integer; virtual;
|
|
procedure AlignItemsToGrid;
|
|
{$IFDEF VCL}
|
|
procedure ChangeScale(M, D: Integer); override;
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
procedure ChangeScale(M, D, MH, DH: Integer); override;
|
|
{$ENDIF VisualCLX}
|
|
procedure Loaded; override;
|
|
procedure Paint; override;
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); override;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); override;
|
|
procedure DefineProperties(Filer: TFiler); override;
|
|
procedure Notification(AComponent: TComponent;
|
|
Operation: TOperation); override;
|
|
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
|
|
procedure SetChildOrder(Component: TComponent; Order: Integer); override;
|
|
procedure ForEachItem(Proc: TForEachItem; Data: Longint); virtual;
|
|
procedure PosChanged; dynamic;
|
|
procedure AfterCustomize; dynamic;
|
|
property ScaleFlags: TSbScaleFlags read FScaleFlags write FScaleFlags;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure SetFontDefault; virtual;
|
|
procedure RemoveItem(Item: TJvSpeedItem);
|
|
procedure RemoveSection(Section: Integer); { delete and free section and items }
|
|
procedure DeleteSection(Section: Integer); { delete section }
|
|
function AddSection(const ACaption: string): Integer;
|
|
procedure AddItem(Section: Integer; Item: TJvSpeedItem);
|
|
function NewItem(AOwner: TComponent; Section: Integer;
|
|
const AName: string): TJvSpeedItem;
|
|
function AcceptDropItem(Item: TJvSpeedItem; X, Y: Integer): Boolean;
|
|
procedure SetEditing(Win: THandle);
|
|
function GetEditing: Boolean;
|
|
function SearchItem(const ItemName: string): TJvSpeedItem;
|
|
function FindItem(Item: TJvSpeedItem; var Section, Index: Integer): Boolean;
|
|
function SearchSection(const ACaption: string): Integer;
|
|
procedure Customize(HelpCtx: THelpContext);
|
|
procedure SaveLayout;
|
|
procedure RestoreLayout;
|
|
procedure LoadFromAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
|
|
procedure SaveToAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
|
|
procedure Load;
|
|
procedure Save;
|
|
function ItemsCount(Section: Integer): Integer;
|
|
function Items(Section, Index: Integer): TJvSpeedItem;
|
|
property EditMode: Boolean read GetEditing;
|
|
property SectionCount: Integer read GetSectionCount;
|
|
property Sections[Index: Integer]: TJvSpeedBarSection read GetSection;
|
|
property Orientation: TBarOrientation read GetOrientation write SetOrientation
|
|
default boHorizontal;
|
|
property OnAddItem: TNotifyEvent read FOnAddItem write FOnAddItem; { for internal use only }
|
|
published
|
|
property Font;
|
|
property ParentFont default False;
|
|
property BoundLines: TBoundLines read FBoundLines write SetBoundLines default [];
|
|
property Position: TBarPosition read FPosition write FPosition default bpAuto;
|
|
{ ensure Position is declared before Align }
|
|
property Align: TAlign read GetAlign write SetAlign default alTop;
|
|
{ ensure Options is declared before BtnOffset... }
|
|
property Options: TJvSpeedBarOptions read FOptions write SetOptions
|
|
default [sbAllowDrag, sbGrayedBtns];
|
|
property BtnOffsetHorz: Integer index 0 read GetButtonsOffset write SetButtonsOffset
|
|
stored True;
|
|
property BtnOffsetVert: Integer index 1 read GetButtonsOffset write SetButtonsOffset
|
|
stored True;
|
|
property BtnWidth: Integer index 0 read GetButtonSize write SetButtonSize;
|
|
property BtnHeight: Integer index 1 read GetButtonSize write SetButtonSize;
|
|
property IniStorage: TJvFormPlacement read GetStorage write SetStorage;
|
|
property Version: Integer read FVersion write FVersion default 0;
|
|
property Wallpaper: TPicture read FWallpaper write SetWallpaper;
|
|
property Images: TCustomImageList read FImages write SetImages;
|
|
{$IFDEF VCL}
|
|
property BiDiMode;
|
|
property DragCursor;
|
|
property ParentBiDiMode;
|
|
property OnEndDock;
|
|
property OnStartDock;
|
|
property Locked;
|
|
{$ENDIF VCL}
|
|
property Constraints;
|
|
property BevelInner;
|
|
property BevelOuter;
|
|
property BevelWidth;
|
|
property BorderWidth;
|
|
property BorderStyle;
|
|
property Color;
|
|
property DragMode;
|
|
property Enabled;
|
|
property ParentColor;
|
|
property ParentShowHint default False;
|
|
property PopupMenu;
|
|
property ShowHint default True;
|
|
property TabOrder;
|
|
property TabStop;
|
|
property Visible;
|
|
property OnApplyAlign: TApplyAlignEvent read FOnApplyAlign write FOnApplyAlign;
|
|
property OnCustomize: TNotifyEvent read FOnCustomize write FOnCustomize;
|
|
property OnPosChanged: TNotifyEvent read FOnPosChanged write FOnPosChanged;
|
|
property OnVisibleChanged: TNotifyEvent read FOnVisibleChanged write FOnVisibleChanged;
|
|
property OnClick;
|
|
property OnDblClick;
|
|
property OnDragDrop;
|
|
property OnDragOver;
|
|
property OnEndDrag;
|
|
property OnEnter;
|
|
property OnExit;
|
|
property OnMouseDown;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
property OnStartDrag;
|
|
property OnContextPopup;
|
|
property OnResize;
|
|
{$IFDEF JVCLThemesEnabled}
|
|
property ParentBackground default True;
|
|
{$ENDIF JVCLThemesEnabled}
|
|
end;
|
|
|
|
TJvSpeedItem = class(TComponent)
|
|
private
|
|
FCaption: string;
|
|
FEditing: Boolean;
|
|
FEnabled: Boolean;
|
|
FButton: TJvSpeedButton;
|
|
FVisible: Boolean;
|
|
FStored: Boolean;
|
|
FParent: TJvSpeedBar;
|
|
FSection: Integer;
|
|
FSectionName: string;
|
|
FImageIndex: TImageIndex;
|
|
procedure SetImageIndex(Value: TImageIndex);
|
|
function GetAction: TBasicAction;
|
|
procedure SetAction(Value: TBasicAction);
|
|
function GetAllowAllUp: Boolean;
|
|
procedure SetAllowAllUp(Value: Boolean);
|
|
function GetAllowTimer: Boolean;
|
|
procedure SetAllowTimer(Value: Boolean);
|
|
function GetBtnCaption: TCaption;
|
|
procedure SetBtnCaption(const Value: TCaption);
|
|
function GetGroupIndex: Integer;
|
|
procedure SetGroupIndex(Value: Integer);
|
|
function GetDown: Boolean;
|
|
procedure SetDown(Value: Boolean);
|
|
function GetGlyph: TBitmap;
|
|
procedure SetGlyph(Value: TBitmap);
|
|
function GetLayout: TButtonLayout;
|
|
procedure SetLayout(Value: TButtonLayout);
|
|
function GetMargin: Integer;
|
|
procedure SetMargin(Value: Integer);
|
|
function GetNumGlyphs: TJvNumGlyphs;
|
|
procedure SetNumGlyphs(Value: TJvNumGlyphs);
|
|
function GetParentShowHint: Boolean;
|
|
procedure SetParentShowHint(Value: Boolean);
|
|
function GetFont: TFont;
|
|
procedure SetFont(Value: TFont);
|
|
function GetParentFont: Boolean;
|
|
procedure SetParentFont(Value: Boolean);
|
|
function IsFontStored: Boolean;
|
|
function GetShowHint: Boolean;
|
|
procedure SetShowHint(Value: Boolean);
|
|
function IsShowHintStored: Boolean;
|
|
function GetSpacing: Integer;
|
|
procedure SetSpacing(Value: Integer);
|
|
function GetCursor: TCursor;
|
|
procedure SetCursor(Value: TCursor);
|
|
function GetHint: string;
|
|
procedure SetHint(const Value: string);
|
|
function GetTag: Longint;
|
|
procedure SetTag(Value: Longint);
|
|
function GetDropDownMenu: TPopupMenu;
|
|
procedure SetDropDownMenu(Value: TPopupMenu);
|
|
function GetMarkDropDown: Boolean;
|
|
procedure SetMarkDropDown(Value: Boolean);
|
|
function GetWordWrap: Boolean;
|
|
procedure SetWordWrap(Value: Boolean);
|
|
function GetOnClick: TNotifyEvent;
|
|
procedure SetOnClick(Value: TNotifyEvent);
|
|
function GetOnDblClick: TNotifyEvent;
|
|
procedure SetOnDblClick(Value: TNotifyEvent);
|
|
function GetOnMouseDown: TMouseEvent;
|
|
procedure SetOnMouseDown(Value: TMouseEvent);
|
|
function GetOnMouseMove: TMouseMoveEvent;
|
|
procedure SetOnMouseMove(Value: TMouseMoveEvent);
|
|
function GetOnMouseUp: TMouseEvent;
|
|
procedure SetOnMouseUp(Value: TMouseEvent);
|
|
function GetOnMouseEnter: TNotifyEvent;
|
|
procedure SetOnMouseEnter(Value: TNotifyEvent);
|
|
function GetOnMouseLeave: TNotifyEvent;
|
|
procedure SetOnMouseLeave(Value: TNotifyEvent);
|
|
function GetCaption: TCaption;
|
|
procedure SetCaption(const Value: TCaption);
|
|
procedure SetEditing(Value: Boolean);
|
|
function GetLeft: Integer;
|
|
function GetTop: Integer;
|
|
procedure SetLeft(Value: Integer);
|
|
procedure SetTop(Value: Integer);
|
|
function GetSection: Integer;
|
|
procedure SetSection(Value: Integer);
|
|
function GetSectionName: string;
|
|
{procedure SetSectionName(const Value: string);}
|
|
procedure ReadSection(Reader: TReader);
|
|
procedure WriteSection(Writer: TWriter);
|
|
procedure ReadSectionName(Reader: TReader);
|
|
procedure WriteSectionName(Writer: TWriter);
|
|
protected
|
|
procedure ReadState(Reader: TReader); override;
|
|
procedure SetName(const Value: TComponentName); override;
|
|
procedure SetEnabled(Value: Boolean);
|
|
procedure SetVisible(Value: Boolean);
|
|
procedure DefineProperties(Filer: TFiler); override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
function HasParent: Boolean; override;
|
|
function GetParentComponent: TComponent; override;
|
|
procedure SetParentComponent(Value: TComponent); override;
|
|
procedure ButtonClick;
|
|
function CheckBtnMenuDropDown: Boolean;
|
|
procedure Click; virtual;
|
|
procedure UpdateSection;
|
|
procedure InvalidateItem;
|
|
property ASection: Integer read GetSection write SetSection;
|
|
property SpeedBar: TJvSpeedBar read FParent;
|
|
property Button: TJvSpeedButton read FButton;
|
|
published
|
|
property Action: TBasicAction read GetAction write SetAction;
|
|
property AllowAllUp: Boolean read GetAllowAllUp write SetAllowAllUp default False;
|
|
property AllowTimer: Boolean read GetAllowTimer write SetAllowTimer default False;
|
|
property BtnCaption: TCaption read GetBtnCaption write SetBtnCaption;
|
|
property Caption: TCaption read GetCaption write SetCaption;
|
|
property GroupIndex: Integer read GetGroupIndex write SetGroupIndex default 0;
|
|
property Down: Boolean read GetDown write SetDown default False;
|
|
property DropDownMenu: TPopupMenu read GetDropDownMenu write SetDropDownMenu;
|
|
property Enabled: Boolean read FEnabled write SetEnabled default True;
|
|
property Font: TFont read GetFont write SetFont stored IsFontStored;
|
|
property Cursor: TCursor read GetCursor write SetCursor default crDefault;
|
|
property Glyph: TBitmap read GetGlyph write SetGlyph;
|
|
property Hint: string read GetHint write SetHint;
|
|
property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1;
|
|
property Layout: TButtonLayout read GetLayout write SetLayout default blGlyphTop;
|
|
property Margin: Integer read GetMargin write SetMargin default -1;
|
|
property MarkDropDown: Boolean read GetMarkDropDown write SetMarkDropDown default True;
|
|
property NumGlyphs: TJvNumGlyphs read GetNumGlyphs write SetNumGlyphs default 1;
|
|
property ParentShowHint: Boolean read GetParentShowHint write SetParentShowHint default True;
|
|
property ParentFont: Boolean read GetParentFont write SetParentFont default True;
|
|
property ShowHint: Boolean read GetShowHint write SetShowHint stored IsShowHintStored;
|
|
property Spacing: Integer read GetSpacing write SetSpacing default 4;
|
|
property Stored: Boolean read FStored write FStored default True;
|
|
property Tag: Longint read GetTag write SetTag default 0;
|
|
property Left: Integer read GetLeft write SetLeft default 0;
|
|
property Top: Integer read GetTop write SetTop default 0;
|
|
property Visible: Boolean read FVisible write SetVisible default False;
|
|
property WordWrap: Boolean read GetWordWrap write SetWordWrap default False;
|
|
property OnClick: TNotifyEvent read GetOnClick write SetOnClick;
|
|
property OnDblClick: TNotifyEvent read GetOnDblClick write SetOnDblClick;
|
|
property OnMouseDown: TMouseEvent read GetOnMouseDown write SetOnMouseDown;
|
|
property OnMouseMove: TMouseMoveEvent read GetOnMouseMove write SetOnMouseMove;
|
|
property OnMouseUp: TMouseEvent read GetOnMouseUp write SetOnMouseUp;
|
|
property OnMouseEnter: TNotifyEvent read GetOnMouseEnter write SetOnMouseEnter;
|
|
property OnMouseLeave: TNotifyEvent read GetOnMouseLeave write SetOnMouseLeave;
|
|
end;
|
|
|
|
TJvSpeedBarSection = class(TComponent)
|
|
private
|
|
FList: TList;
|
|
FTitle: string;
|
|
FParent: TJvSpeedBar;
|
|
function Get(Index: Integer): TJvSpeedItem;
|
|
procedure Put(Index: Integer; Item: TJvSpeedItem);
|
|
function GetCount: Integer;
|
|
function GetTitle: string;
|
|
procedure SetTitle(const Value: string);
|
|
function GetIndex: Integer;
|
|
procedure SetIndex(Value: Integer);
|
|
procedure SetSpeedBar(Value: TJvSpeedBar);
|
|
procedure ValidateCaption(const NewCaption: string);
|
|
protected
|
|
procedure SetParentComponent(Value: TComponent); override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
function HasParent: Boolean; override;
|
|
function GetParentComponent: TComponent; override;
|
|
procedure Clear;
|
|
procedure RemoveItem(Item: TJvSpeedItem);
|
|
property Count: Integer read GetCount;
|
|
property Items[Index: Integer]: TJvSpeedItem read Get write Put; default;
|
|
property List: TList read FList; { for internal use only }
|
|
property SpeedBar: TJvSpeedBar read FParent write SetSpeedBar stored False;
|
|
published
|
|
property Caption: string read GetTitle write SetTitle;
|
|
property Index: Integer read GetIndex write SetIndex stored False;
|
|
end;
|
|
|
|
TJvBtnControl = class(TJvCustomControl)
|
|
private
|
|
FImage: TJvButtonImage;
|
|
FSpacing: Integer;
|
|
FMargin: Integer;
|
|
FLayout: TButtonLayout;
|
|
FImageIndex: Integer;
|
|
FImages: TCustomImageList;
|
|
function GetCaption: TCaption;
|
|
function GetGlyph: TBitmap;
|
|
function GetNumGlyphs: TJvNumGlyphs;
|
|
function GetWordWrap: Boolean;
|
|
function GetAlignment: TAlignment;
|
|
procedure SetAlignment(Value: TAlignment);
|
|
procedure SetCaption(const Value: TCaption);
|
|
procedure SetNumGlyphs(Value: TJvNumGlyphs);
|
|
procedure SetGlyph(Value: TBitmap);
|
|
procedure SetWordWrap(Value: Boolean);
|
|
protected
|
|
{$IFDEF VCL}
|
|
procedure CreateParams(var Params: TCreateParams); override;
|
|
{$ENDIF VCL}
|
|
procedure Paint; override;
|
|
procedure BoundsChanged; override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure AssignSpeedItem(Item: TJvSpeedItem);
|
|
procedure Activate(Rect: TRect);
|
|
procedure ReleaseHandle;
|
|
property Alignment: TAlignment read GetAlignment write SetAlignment;
|
|
property Caption: TCaption read GetCaption write SetCaption;
|
|
property Glyph: TBitmap read GetGlyph write SetGlyph;
|
|
property NumGlyphs: TJvNumGlyphs read GetNumGlyphs write SetNumGlyphs;
|
|
property Spacing: Integer read FSpacing write FSpacing;
|
|
property ImageIndex: Integer read FImageIndex write FImageIndex;
|
|
property Images: TCustomImageList read FImages write FImages;
|
|
property Margin: Integer read FMargin write FMargin;
|
|
property Layout: TButtonLayout read FLayout write FLayout;
|
|
property WordWrap: Boolean read GetWordWrap write SetWordWrap;
|
|
property Font;
|
|
end;
|
|
|
|
{ Utility routines for SpeedBar Editors }
|
|
|
|
function FindSpeedBar(const Pos: TPoint): TJvSpeedBar;
|
|
procedure DrawCellButton(Grid: TDrawGrid; R: TRect; Item: TJvSpeedItem;
|
|
Image: TJvButtonImage; ARightToLeft: Boolean = False);
|
|
function NewSpeedSection(ASpeedBar: TJvSpeedBar; const ACaption: string): Integer;
|
|
function NewSpeedItem(AOwner: TComponent; ASpeedBar: TJvSpeedBar; Section: Integer;
|
|
const AName: string): TJvSpeedItem;
|
|
|
|
{$IFDEF UNITVERSIONING}
|
|
const
|
|
UnitVersioning: TUnitVersionInfo = (
|
|
RCSfile: '$RCSfile: JvSpeedbar.pas,v $';
|
|
Revision: '$Revision: 1.57 $';
|
|
Date: '$Date: 2005/10/28 08:37:23 $';
|
|
LogPath: 'JVCL\run'
|
|
);
|
|
{$ENDIF UNITVERSIONING}
|
|
|
|
implementation
|
|
|
|
uses
|
|
Math, Consts,
|
|
JvJVCLUtils, JvJCLUtils, JvSpeedbarSetupForm, JvResources;
|
|
|
|
const
|
|
DefaultButtonSize: TPoint = (X: DefButtonWidth; Y: DefButtonHeight);
|
|
DragFrameWidth = 3;
|
|
StartDragOffset = 4;
|
|
|
|
// (rom) changed to var
|
|
var
|
|
Registered: Boolean = False;
|
|
|
|
const
|
|
Alignments: array [TAlignment] of Word = (DT_LEFT, DT_RIGHT, DT_CENTER);
|
|
|
|
// (rom) moved here to make JvMaxMin obsolete
|
|
procedure SwapInt(var Int1, Int2: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
I := Int1;
|
|
Int1 := Int2;
|
|
Int2 := I;
|
|
end;
|
|
|
|
//=== { TJvSpeedBarSection } =================================================
|
|
|
|
constructor TJvSpeedBarSection.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FList := TList.Create;
|
|
FTitle := '';
|
|
end;
|
|
|
|
destructor TJvSpeedBarSection.Destroy;
|
|
begin
|
|
Clear;
|
|
if FParent <> nil then
|
|
FParent.DeleteSection(Index);
|
|
FList.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TJvSpeedBarSection.Clear;
|
|
begin
|
|
while FList.Count > 0 do
|
|
begin
|
|
TJvSpeedItem(FList[0]).Free;
|
|
FList.Delete(0);
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedBarSection.Get(Index: Integer): TJvSpeedItem;
|
|
begin
|
|
Result := TJvSpeedItem(FList[Index]);
|
|
end;
|
|
|
|
procedure TJvSpeedBarSection.Put(Index: Integer; Item: TJvSpeedItem);
|
|
begin
|
|
FList[Index] := Item;
|
|
end;
|
|
|
|
function TJvSpeedBarSection.GetCount: Integer;
|
|
begin
|
|
Result := FList.Count;
|
|
end;
|
|
|
|
function TJvSpeedBarSection.GetIndex: Integer;
|
|
begin
|
|
if FParent <> nil then
|
|
Result := FParent.FSections.IndexOf(Self)
|
|
else
|
|
Result := -1;
|
|
end;
|
|
|
|
procedure TJvSpeedBarSection.SetIndex(Value: Integer);
|
|
var
|
|
CurIndex, Count: Integer;
|
|
begin
|
|
CurIndex := GetIndex;
|
|
if CurIndex >= 0 then
|
|
begin
|
|
Count := FParent.FSections.Count;
|
|
if Value < 0 then
|
|
Value := 0;
|
|
if Value >= Count then
|
|
Value := Count - 1;
|
|
if Value <> CurIndex then
|
|
begin
|
|
FParent.FSections.Delete(CurIndex);
|
|
FParent.FSections.Insert(Value, Self);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedBarSection.HasParent: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TJvSpeedBarSection.SetSpeedBar(Value: TJvSpeedBar);
|
|
var
|
|
CurIndex: Integer;
|
|
begin
|
|
CurIndex := GetIndex;
|
|
if FParent <> nil then
|
|
FParent.DeleteSection(Index);
|
|
if Value <> nil then
|
|
Value.AppendSection(Self);
|
|
if CurIndex >= 0 then
|
|
Index := CurIndex;
|
|
end;
|
|
|
|
function TJvSpeedBarSection.GetParentComponent: TComponent;
|
|
begin
|
|
Result := FParent;
|
|
end;
|
|
|
|
procedure TJvSpeedBarSection.SetParentComponent(Value: TComponent);
|
|
begin
|
|
SpeedBar := Value as TJvSpeedBar;
|
|
end;
|
|
|
|
procedure TJvSpeedBarSection.RemoveItem(Item: TJvSpeedItem);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
I := FList.IndexOf(Item);
|
|
if I >= 0 then
|
|
begin
|
|
Item.FButton.Parent := nil;
|
|
Item.FParent := nil;
|
|
Item.FSection := -1;
|
|
FList.Delete(I);
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBarSection.ValidateCaption(const NewCaption: string);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if FParent <> nil then
|
|
begin
|
|
I := FParent.SearchSection(NewCaption);
|
|
if (I <> Index) and (I >= 0) then
|
|
raise EJvSpeedbarError.CreateRes(@SDuplicateString);
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBarSection.SetTitle(const Value: string);
|
|
begin
|
|
if not (csLoading in ComponentState) then
|
|
ValidateCaption(Value);
|
|
FTitle := Value;
|
|
end;
|
|
|
|
function TJvSpeedBarSection.GetTitle: string;
|
|
begin
|
|
Result := FTitle;
|
|
end;
|
|
|
|
//=== { TJvSpeedBarButton } ==================================================
|
|
|
|
type
|
|
TJvSpeedBarButton = class(TJvSpeedButton)
|
|
private
|
|
FItem: TJvSpeedItem;
|
|
FBtn: TJvBtnControl;
|
|
procedure InvalidateGlyph;
|
|
protected
|
|
procedure VisibleChanged; override;
|
|
{$IFDEF VCL}
|
|
procedure WndProc(var Msg: TMessage); override;
|
|
{$ENDIF VCL}
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); override;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); override;
|
|
procedure PaintImage(Canvas: TCanvas; ARect: TRect; const Offset: TPoint;
|
|
AState: TJvButtonState; DrawMark: Boolean); override;
|
|
procedure Paint; override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
|
|
end;
|
|
|
|
constructor TJvSpeedBarButton.Create(AOwner: TComponent);
|
|
begin
|
|
FItem := TJvSpeedItem(AOwner);
|
|
{ Ensure FItem is assigned before inherited Create }
|
|
inherited Create(AOwner);
|
|
Visible := False;
|
|
Style := bsNew;
|
|
ParentShowHint := True;
|
|
ParentFont := True;
|
|
end;
|
|
|
|
destructor TJvSpeedBarButton.Destroy;
|
|
begin
|
|
FBtn.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TJvSpeedBarButton.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
|
|
begin
|
|
if FItem.SpeedBar <> nil then
|
|
begin
|
|
case FItem.SpeedBar.Orientation of
|
|
boHorizontal:
|
|
ATop := Max(FItem.SpeedBar.FOffset.Y, ATop);
|
|
boVertical:
|
|
ALeft := Max(FItem.SpeedBar.FOffset.X, ALeft);
|
|
end;
|
|
end;
|
|
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
|
|
end;
|
|
|
|
procedure TJvSpeedBarButton.VisibleChanged;
|
|
begin
|
|
if Visible then
|
|
begin
|
|
ControlStyle := ControlStyle - [csNoDesignVisible];
|
|
Invalidate;
|
|
end
|
|
else
|
|
ControlStyle := ControlStyle + [csNoDesignVisible];
|
|
inherited;
|
|
end;
|
|
|
|
{$IFDEF VCL}
|
|
procedure TJvSpeedBarButton.WndProc(var Msg: TMessage);
|
|
begin
|
|
if FItem.FEditing and (csDesigning in ComponentState) and
|
|
(Msg.Msg >= WM_MOUSEFIRST) and (Msg.Msg <= WM_MOUSELAST) then
|
|
begin
|
|
if (Msg.Msg = WM_LBUTTONDOWN) and not Visible then
|
|
inherited WndProc(Msg)
|
|
else
|
|
Dispatch(Msg);
|
|
end
|
|
else
|
|
inherited WndProc(Msg);
|
|
end;
|
|
{$ENDIF VCL}
|
|
|
|
procedure TJvSpeedBarButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
if FItem.FEditing and Visible and (Button = mbLeft) and
|
|
(FItem.SpeedBar <> nil) then
|
|
begin
|
|
P := ClientToScreen(Point(FItem.SpeedBar.BtnWidth {div 2},
|
|
FItem.SpeedBar.BtnHeight {div 2}));
|
|
{$IFDEF VCL}
|
|
X := P.X;
|
|
Y := P.Y;
|
|
{$ENDIF VCL}
|
|
if FBtn = nil then
|
|
begin
|
|
{$IFDEF VCL}
|
|
SetCursorPos(X, Y);
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
Mouse.CursorPos := P;
|
|
{$ENDIF VisualCLX}
|
|
FBtn := TJvBtnControl.Create(Self);
|
|
FBtn.AssignSpeedItem(FItem);
|
|
end;
|
|
BringToFront;
|
|
end
|
|
else
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TJvSpeedBarButton.MouseMove(Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
P: TPoint;
|
|
R: TRect;
|
|
begin
|
|
if FItem.FEditing and (FBtn <> nil) then
|
|
begin
|
|
P := ClientToScreen(Point(X - (FBtn.Width {div 2}),
|
|
Y - (FBtn.Height {div 2})));
|
|
X := P.X;
|
|
Y := P.Y;
|
|
if FItem.SpeedBar <> nil then
|
|
begin
|
|
Visible := False;
|
|
if csDesigning in ComponentState then
|
|
begin
|
|
R := BoundsRect;
|
|
InvalidateRect(FItem.SpeedBar.Handle, @R, True);
|
|
end;
|
|
P := FItem.SpeedBar.ScreenToClient(P);
|
|
if PtInRect(FItem.SpeedBar.ClientRect, P) then
|
|
begin
|
|
FBtn.Activate(Bounds(X, Y, FBtn.Width, FBtn.Height));
|
|
end
|
|
else
|
|
FBtn.ReleaseHandle;
|
|
end;
|
|
end
|
|
else
|
|
inherited MouseMove(Shift, X, Y);
|
|
end;
|
|
|
|
procedure TJvSpeedBarButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
if FItem.FEditing and (FBtn <> nil) then
|
|
begin
|
|
X := X - (FBtn.Width {div 2});
|
|
Y := Y - (FBtn.Height {div 2});
|
|
FBtn.Free;
|
|
FBtn := nil;
|
|
P := ClientToScreen(Point(X, Y));
|
|
if FItem.SpeedBar <> nil then
|
|
begin
|
|
P := FItem.SpeedBar.ScreenToClient(P);
|
|
if PtInRect(FItem.SpeedBar.ClientRect, P) then
|
|
begin
|
|
if not FItem.SpeedBar.AcceptDropItem(FItem, P.X, P.Y) then
|
|
begin
|
|
SendMessage(FItem.SpeedBar.FEditWin, CM_SPEEDBARCHANGED, SBR_CHANGED,
|
|
Longint(FItem.SpeedBar));
|
|
end
|
|
else
|
|
begin
|
|
SendMessage(FItem.SpeedBar.FEditWin, CM_SPEEDBARCHANGED, SBR_BTNSELECT,
|
|
Longint(FItem));
|
|
Invalidate;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
SendToBack;
|
|
FItem.Visible := False;
|
|
SendMessage(FItem.SpeedBar.FEditWin, CM_SPEEDBARCHANGED, SBR_CHANGED,
|
|
Longint(FItem.SpeedBar));
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TJvSpeedBarButton.InvalidateGlyph;
|
|
begin
|
|
TJvxButtonGlyph(ButtonGlyph).Invalidate;
|
|
end;
|
|
|
|
procedure TJvSpeedBarButton.PaintImage(Canvas: TCanvas; ARect: TRect; const Offset: TPoint;
|
|
AState: TJvButtonState; DrawMark: Boolean);
|
|
begin
|
|
if FItem.SpeedBar <> nil then
|
|
begin
|
|
TJvxButtonGlyph(ButtonGlyph).DrawEx(Canvas, ARect, Offset, Caption, Layout,
|
|
Margin, Spacing, DrawMark, FItem.SpeedBar.Images, FItem.FImageIndex,
|
|
AState,
|
|
{$IFDEF VCL}
|
|
DrawTextBiDiModeFlags(Alignments[Alignment])
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
Alignments[Alignment]
|
|
{$ENDIF VisualCLX}
|
|
);
|
|
end
|
|
else
|
|
inherited PaintImage(Canvas, ARect, Offset, AState, DrawMark);
|
|
end;
|
|
|
|
procedure TJvSpeedBarButton.Paint;
|
|
begin
|
|
if Visible then
|
|
inherited Paint;
|
|
end;
|
|
|
|
//=== { TJvSpeedItem } =======================================================
|
|
|
|
constructor TJvSpeedItem.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FButton := TJvSpeedBarButton.Create(Self);
|
|
FButton.Visible := False;
|
|
FButton.SetBounds(0, 0, DefaultButtonSize.X, DefaultButtonSize.Y);
|
|
FCaption := '';
|
|
ShowHint := True;
|
|
ParentShowHint := True;
|
|
FVisible := False;
|
|
FStored := True;
|
|
FEnabled := True;
|
|
FEditing := False;
|
|
FParent := nil;
|
|
FImageIndex := -1;
|
|
end;
|
|
|
|
destructor TJvSpeedItem.Destroy;
|
|
begin
|
|
FVisible := False;
|
|
if FParent <> nil then
|
|
FParent.RemoveItem(Self);
|
|
FButton.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetCaption: TCaption;
|
|
begin
|
|
Result := TCaption(FCaption);
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetCaption(const Value: TCaption);
|
|
var
|
|
ChangeHint: Boolean;
|
|
begin
|
|
ChangeHint := (Owner = nil) or not (Owner is TControl) or
|
|
not (csLoading in TControl(Owner).ComponentState) and
|
|
(Caption = GetShortHint(Hint));
|
|
FCaption := Value;
|
|
if ChangeHint then
|
|
begin
|
|
if Pos('|', Value) = 0 then
|
|
begin
|
|
if Pos('|', Hint) = 0 then
|
|
Hint := Value + '|'
|
|
else
|
|
Hint := Value + '|' + GetLongHint(Hint);
|
|
end
|
|
else
|
|
begin
|
|
if GetLongHint(Value) = '' then
|
|
Hint := GetShortHint(Value) + '|' + GetLongHint(Hint)
|
|
else
|
|
Hint := Value;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetName(const Value: TComponentName);
|
|
var
|
|
ChangeText: Boolean;
|
|
begin
|
|
ChangeText := (Name = Caption) and
|
|
((Owner = nil) or not (Owner is TControl) or
|
|
not (csLoading in TControl(Owner).ComponentState));
|
|
inherited SetName(Value);
|
|
if ChangeText then
|
|
Caption := Value;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetEditing(Value: Boolean);
|
|
begin
|
|
FEditing := Value;
|
|
if FEditing then
|
|
begin
|
|
FButton.Enabled := True;
|
|
FButton.Flat := False;
|
|
end
|
|
else
|
|
begin
|
|
SetEnabled(FEnabled);
|
|
if SpeedBar <> nil then
|
|
FButton.Flat := (sbFlatBtns in SpeedBar.Options);
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedItem.HasParent: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.DefineProperties(Filer: TFiler);
|
|
|
|
function DoWrite: Boolean;
|
|
begin
|
|
if Assigned(Filer.Ancestor) then
|
|
Result := GetSectionName <> TJvSpeedItem(Filer.Ancestor).GetSectionName
|
|
else
|
|
Result := True;
|
|
end;
|
|
|
|
begin
|
|
inherited DefineProperties(Filer);
|
|
Filer.DefineProperty('Section', ReadSection, WriteSection, False);
|
|
Filer.DefineProperty('SectionName', ReadSectionName, WriteSectionName, DoWrite);
|
|
end;
|
|
|
|
procedure TJvSpeedItem.ReadSectionName(Reader: TReader);
|
|
begin
|
|
FSectionName := Reader.ReadString;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.WriteSectionName(Writer: TWriter);
|
|
begin
|
|
Writer.WriteString(GetSectionName);
|
|
end;
|
|
|
|
procedure TJvSpeedItem.ReadSection(Reader: TReader);
|
|
begin
|
|
FSection := Reader.ReadInteger;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.WriteSection(Writer: TWriter);
|
|
begin
|
|
UpdateSection;
|
|
Writer.WriteInteger(FSection);
|
|
end;
|
|
|
|
function TJvSpeedItem.GetParentComponent: TComponent;
|
|
begin
|
|
Result := FParent;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetParentComponent(Value: TComponent);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not (csLoading in ComponentState) then
|
|
begin
|
|
if FParent <> nil then
|
|
FParent.RemoveItem(Self);
|
|
if (Value <> nil) and (Value is TJvSpeedBar) then
|
|
begin
|
|
I := TJvSpeedBar(Value).SearchSection(FSectionName);
|
|
if I >= 0 then
|
|
FSection := I;
|
|
TJvSpeedBar(Value).AddItem(FSection, Self);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetImageIndex(Value: TImageIndex);
|
|
begin
|
|
if Value <> FImageIndex then
|
|
begin
|
|
FImageIndex := Value;
|
|
TJvSpeedBarButton(FButton).InvalidateGlyph;
|
|
FButton.Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.ReadState(Reader: TReader);
|
|
begin
|
|
inherited ReadState(Reader);
|
|
if Reader.Parent is TJvSpeedBar then
|
|
begin
|
|
if FSectionName <> '' then
|
|
FSection := TJvSpeedBar(Reader.Parent).SearchSection(FSectionName);
|
|
TJvSpeedBar(Reader.Parent).AddItem(Max(FSection, 0), Self);
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetSection: Integer;
|
|
begin
|
|
UpdateSection;
|
|
Result := FSection;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetSection(Value: Integer);
|
|
begin
|
|
if SpeedBar = nil then
|
|
FSection := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetSectionName: string;
|
|
begin
|
|
UpdateSection;
|
|
if FSection >= 0 then
|
|
Result := FParent.Sections[FSection].Caption
|
|
else
|
|
Result := FSectionName;
|
|
end;
|
|
|
|
{
|
|
procedure TJvSpeedItem.SetSectionName(const Value: string);
|
|
begin
|
|
if FParent <> nil then FSection := FParent.SearchSection(Value)
|
|
else FSection := -1;
|
|
FSectionName := Value;
|
|
end;
|
|
}
|
|
|
|
procedure TJvSpeedItem.InvalidateItem;
|
|
begin
|
|
FSection := -1;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.UpdateSection;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if FParent <> nil then
|
|
FParent.FindItem(Self, FSection, I)
|
|
else
|
|
FSection := -1;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetEnabled(Value: Boolean);
|
|
begin
|
|
if (FButton.Enabled <> Value) or (FEnabled <> Value) then
|
|
begin
|
|
FEnabled := Value;
|
|
if not FEditing then
|
|
begin
|
|
if (SpeedBar <> nil) and Value then
|
|
FButton.Enabled := (Value and SpeedBar.Enabled)
|
|
else
|
|
FButton.Enabled := Value;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetVisible(Value: Boolean);
|
|
begin
|
|
if (FButton.Visible <> Value) or (FVisible <> Value) or
|
|
(Value and (FButton.Parent = nil)) then
|
|
begin
|
|
FVisible := Value;
|
|
if (SpeedBar <> nil) and Value then
|
|
FButton.Visible := Value and SpeedBar.Visible
|
|
else
|
|
FButton.Visible := Value;
|
|
if Value then
|
|
FButton.Parent := SpeedBar;
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetAllowAllUp: Boolean;
|
|
begin
|
|
Result := FButton.AllowAllUp;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetAllowAllUp(Value: Boolean);
|
|
begin
|
|
FButton.AllowAllUp := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetAllowTimer: Boolean;
|
|
begin
|
|
Result := FButton.AllowTimer;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetAllowTimer(Value: Boolean);
|
|
begin
|
|
FButton.AllowTimer := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetBtnCaption: TCaption;
|
|
begin
|
|
Result := FButton.Caption;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetBtnCaption(const Value: TCaption);
|
|
begin
|
|
FButton.Caption := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetGroupIndex: Integer;
|
|
begin
|
|
Result := FButton.GroupIndex;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetGroupIndex(Value: Integer);
|
|
begin
|
|
FButton.GroupIndex := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetOnClick: TNotifyEvent;
|
|
begin
|
|
Result := FButton.OnClick;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetOnClick(Value: TNotifyEvent);
|
|
begin
|
|
FButton.OnClick := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetOnDblClick: TNotifyEvent;
|
|
begin
|
|
Result := FButton.OnDblClick;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetOnDblClick(Value: TNotifyEvent);
|
|
begin
|
|
FButton.OnDblClick := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetOnMouseDown: TMouseEvent;
|
|
begin
|
|
Result := FButton.OnMouseDown;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetOnMouseDown(Value: TMouseEvent);
|
|
begin
|
|
FButton.OnMouseDown := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetOnMouseMove: TMouseMoveEvent;
|
|
begin
|
|
Result := FButton.OnMouseMove;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetOnMouseMove(Value: TMouseMoveEvent);
|
|
begin
|
|
FButton.OnMouseMove := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetOnMouseUp: TMouseEvent;
|
|
begin
|
|
Result := FButton.OnMouseUp;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetOnMouseUp(Value: TMouseEvent);
|
|
begin
|
|
FButton.OnMouseUp := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetOnMouseEnter: TNotifyEvent;
|
|
begin
|
|
Result := FButton.OnMouseEnter;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetOnMouseEnter(Value: TNotifyEvent);
|
|
begin
|
|
FButton.OnMouseEnter := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetOnMouseLeave: TNotifyEvent;
|
|
begin
|
|
Result := FButton.OnMouseLeave;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetOnMouseLeave(Value: TNotifyEvent);
|
|
begin
|
|
FButton.OnMouseLeave := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetDown: Boolean;
|
|
begin
|
|
Result := FButton.Down;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetDown(Value: Boolean);
|
|
begin
|
|
FButton.Down := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetGlyph: TBitmap;
|
|
begin
|
|
Result := FButton.Glyph;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetGlyph(Value: TBitmap);
|
|
begin
|
|
FButton.Glyph := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetLayout: TButtonLayout;
|
|
begin
|
|
Result := FButton.Layout;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetLayout(Value: TButtonLayout);
|
|
begin
|
|
FButton.Layout := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetMargin: Integer;
|
|
begin
|
|
Result := FButton.Margin;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetMargin(Value: Integer);
|
|
begin
|
|
FButton.Margin := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetNumGlyphs: TJvNumGlyphs;
|
|
begin
|
|
Result := FButton.NumGlyphs;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetNumGlyphs(Value: TJvNumGlyphs);
|
|
begin
|
|
FButton.NumGlyphs := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetParentShowHint: Boolean;
|
|
begin
|
|
Result := FButton.ParentShowHint;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetParentShowHint(Value: Boolean);
|
|
begin
|
|
FButton.ParentShowHint := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetShowHint: Boolean;
|
|
begin
|
|
Result := FButton.ShowHint;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetShowHint(Value: Boolean);
|
|
begin
|
|
FButton.ShowHint := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetFont: TFont;
|
|
begin
|
|
Result := FButton.Font;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetFont(Value: TFont);
|
|
begin
|
|
FButton.Font := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetParentFont: Boolean;
|
|
begin
|
|
Result := FButton.ParentFont;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetParentFont(Value: Boolean);
|
|
begin
|
|
FButton.ParentFont := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.IsFontStored: Boolean;
|
|
begin
|
|
Result := not ParentFont;
|
|
end;
|
|
|
|
function TJvSpeedItem.IsShowHintStored: Boolean;
|
|
begin
|
|
Result := not ParentShowHint;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetSpacing: Integer;
|
|
begin
|
|
Result := FButton.Spacing;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetSpacing(Value: Integer);
|
|
begin
|
|
FButton.Spacing := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetCursor: TCursor;
|
|
begin
|
|
Result := FButton.Cursor;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetCursor(Value: TCursor);
|
|
begin
|
|
FButton.Cursor := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetHint: string;
|
|
begin
|
|
Result := FButton.Hint;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetHint(const Value: string);
|
|
begin
|
|
FButton.Hint := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetAction: TBasicAction;
|
|
begin
|
|
Result := FButton.Action;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetAction(Value: TBasicAction);
|
|
begin
|
|
FButton.Action := Value;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.ButtonClick;
|
|
begin
|
|
FButton.ButtonClick;
|
|
end;
|
|
|
|
function TJvSpeedItem.CheckBtnMenuDropDown: Boolean;
|
|
begin
|
|
Result := FButton.CheckBtnMenuDropDown;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.Click;
|
|
begin
|
|
FButton.Click;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetTag: Longint;
|
|
begin
|
|
Result := inherited Tag;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetTag(Value: Longint);
|
|
begin
|
|
inherited Tag := Value;
|
|
FButton.Tag := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetDropDownMenu: TPopupMenu;
|
|
begin
|
|
Result := FButton.DropDownMenu;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetDropDownMenu(Value: TPopupMenu);
|
|
begin
|
|
FButton.DropDownMenu := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetMarkDropDown: Boolean;
|
|
begin
|
|
Result := FButton.MarkDropDown;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetMarkDropDown(Value: Boolean);
|
|
begin
|
|
FButton.MarkDropDown := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetWordWrap: Boolean;
|
|
begin
|
|
Result := FButton.WordWrap;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetWordWrap(Value: Boolean);
|
|
begin
|
|
FButton.WordWrap := Value;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetLeft: Integer;
|
|
begin
|
|
Result := FButton.Left;
|
|
end;
|
|
|
|
function TJvSpeedItem.GetTop: Integer;
|
|
begin
|
|
Result := FButton.Top;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetLeft(Value: Integer);
|
|
begin
|
|
FButton.Left := Value;
|
|
end;
|
|
|
|
procedure TJvSpeedItem.SetTop(Value: Integer);
|
|
begin
|
|
FButton.Top := Value;
|
|
end;
|
|
|
|
const
|
|
InternalVer = 1;
|
|
|
|
//=== { TJvSpeedBar } ========================================================
|
|
|
|
constructor TJvSpeedBar.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FSections := TList.Create;
|
|
FButtonSize := DefaultButtonSize;
|
|
FButtonStyle := bsNew;
|
|
FWallpaper := TPicture.Create;
|
|
FWallpaper.OnChange := WallpaperChanged;
|
|
FIniLink := TJvIniLink.Create;
|
|
FIniLink.OnSave := IniSave;
|
|
FIniLink.OnLoad := IniLoad;
|
|
FOffset.X := MinButtonsOffset;
|
|
FOffset.Y := FOffset.X;
|
|
Height := 2 * FOffset.Y + DefaultButtonSize.Y;
|
|
FRowCount := 1;
|
|
FEditWin := NullHandle;
|
|
FOptions := [sbAllowDrag, sbGrayedBtns];
|
|
ControlStyle := ControlStyle - [csSetCaption, csReplicatable];
|
|
IncludeThemeStyle(Self, [csNeedsBorderPaint, csParentBackground]);
|
|
ParentShowHint := False;
|
|
ShowHint := True;
|
|
SetFontDefault;
|
|
inherited Align := alTop;
|
|
FAlign := alTop;
|
|
UpdateGridSize;
|
|
FImageChangeLink := TChangeLink.Create;
|
|
FImageChangeLink.OnChange := ImageListChange;
|
|
if not Registered then
|
|
begin
|
|
{$IFDEF COMPILER7_UP}
|
|
GroupDescendentsWith(TJvSpeedItem, TControl);
|
|
GroupDescendentsWith(TJvSpeedBarSection, TControl);
|
|
{$ENDIF COMPILER7_UP}
|
|
RegisterClasses([TJvSpeedItem, TJvSpeedBarSection, TJvSpeedBarButton]);
|
|
Registered := True;
|
|
end;
|
|
end;
|
|
|
|
destructor TJvSpeedBar.Destroy;
|
|
begin
|
|
FOnVisibleChanged := nil;
|
|
FOnApplyAlign := nil;
|
|
FOnPosChanged := nil;
|
|
FIniLink.Free;
|
|
FWallpaper.OnChange := nil;
|
|
FWallpaper.Free;
|
|
FWallpaper := nil;
|
|
if FEditWin <> NullHandle then
|
|
begin
|
|
SendMessage(FEditWin, CM_SPEEDBARCHANGED, SBR_DESTROYED, Longint(Self));
|
|
FEditWin := NullHandle;
|
|
end;
|
|
ClearSections;
|
|
FSections.Free;
|
|
FImageChangeLink.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.Loaded;
|
|
begin
|
|
inherited Loaded;
|
|
if (FReserved = 0) and FFix then
|
|
begin { fix previous version error }
|
|
inherited Align := alTop;
|
|
FAlign := alTop;
|
|
end;
|
|
UpdateGridSize;
|
|
ForEachItem(SetItemButtonSize, 0);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.ReadData(Reader: TReader);
|
|
begin
|
|
FReserved := Reader.ReadInteger;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.WriteData(Writer: TWriter);
|
|
begin
|
|
Writer.WriteInteger(InternalVer);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.ReadAllowDrag(Reader: TReader);
|
|
begin
|
|
if Reader.ReadBoolean then
|
|
Options := Options + [sbAllowDrag]
|
|
else
|
|
Options := Options - [sbAllowDrag];
|
|
end;
|
|
|
|
procedure TJvSpeedBar.ReadDesignStyle(Reader: TReader);
|
|
begin
|
|
FDesignStyle := Reader.ReadBoolean;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.WriteDesignStyle(Writer: TWriter);
|
|
begin
|
|
Writer.WriteBoolean(NewStyleControls);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.ReadSections(Reader: TReader);
|
|
var
|
|
TmpList: TStringList;
|
|
I: Integer;
|
|
begin
|
|
TmpList := TStringList.Create;
|
|
try
|
|
Reader.ReadListBegin;
|
|
while not Reader.EndOfList do
|
|
TmpList.AddObject(Reader.ReadString, nil);
|
|
Reader.ReadListEnd;
|
|
if (Reader.Ancestor = nil) or (TmpList.Count > 0) then
|
|
for I := 0 to TmpList.Count - 1 do
|
|
if SearchSection(TmpList[I]) < 0 then
|
|
AddSection(TmpList[I]);
|
|
finally
|
|
TmpList.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.WriteSections(Writer: TWriter);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Writer.WriteListBegin;
|
|
for I := 0 to FSections.Count - 1 do
|
|
Writer.WriteString(Sections[I].Caption);
|
|
Writer.WriteListEnd;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.DefineProperties(Filer: TFiler);
|
|
begin
|
|
inherited DefineProperties(Filer);
|
|
Filer.DefineProperty('Sections', ReadSections, WriteSections, False);
|
|
Filer.DefineProperty('NewStyle', ReadDesignStyle, WriteDesignStyle, False);
|
|
Filer.DefineProperty('InternalVer', ReadData, WriteData,Filer.Ancestor = nil);
|
|
{ AllowDrag reading for backward compatibility only }
|
|
Filer.DefineProperty('AllowDrag', ReadAllowDrag, nil, False);
|
|
end;
|
|
|
|
function TJvSpeedBar.GetSection(Index: Integer): TJvSpeedBarSection;
|
|
begin
|
|
Result := TJvSpeedBarSection(FSections[Index]);
|
|
end;
|
|
|
|
function TJvSpeedBar.GetSectionCount: Integer;
|
|
begin
|
|
Result := FSections.Count;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.ForEachItem(Proc: TForEachItem; Data: Longint);
|
|
var
|
|
I, Idx: Integer;
|
|
Sect: TJvSpeedBarSection;
|
|
begin
|
|
for I := 0 to FSections.Count - 1 do
|
|
if FSections[I] <> nil then
|
|
begin
|
|
Sect := TJvSpeedBarSection(FSections[I]);
|
|
for Idx := 0 to Sect.Count - 1 do
|
|
begin
|
|
if (Sect[Idx] <> nil) and Assigned(Proc) then
|
|
Proc(TJvSpeedItem(Sect[Idx]), Data);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedBar.MinButtonsOffset: Integer;
|
|
begin
|
|
Result := BorderWidth + 2 * Ord(not (sbFlatBtns in Options));
|
|
if BevelOuter <> bvNone then
|
|
Inc(Result, BevelWidth);
|
|
if BevelInner <> bvNone then
|
|
Inc(Result, BevelWidth);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetItemVisible(Item: TJvSpeedItem; Data: Longint);
|
|
var
|
|
ItemVisible: Boolean;
|
|
begin
|
|
ItemVisible := Item.Visible and Self.Visible;
|
|
Item.FButton.Visible := ItemVisible;
|
|
if (Item.FButton.Parent <> Self) and ItemVisible then
|
|
Item.FButton.Parent := Self;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetItemEnabled(Item: TJvSpeedItem; Data: Longint);
|
|
begin
|
|
Item.FButton.Enabled := Item.Enabled and Self.Enabled;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetItemButtonSize(Item: TJvSpeedItem; Data: Longint);
|
|
begin
|
|
ApplyItemSize(Item, Data);
|
|
Item.Visible := Item.Visible; { update visible and parent after loading }
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SwapItemBounds(Item: TJvSpeedItem; Data: Longint);
|
|
begin
|
|
Item.FButton.SetBounds(Item.Top, Item.Left, FButtonSize.X, FButtonSize.Y);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetFontDefault;
|
|
{$IFDEF VCL}
|
|
var
|
|
NCMetrics: TNonClientMetrics;
|
|
begin
|
|
ParentFont := False;
|
|
with Font do
|
|
begin
|
|
NCMetrics.cbSize := SizeOf(TNonClientMetrics);
|
|
if SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NCMetrics, 0) then
|
|
begin
|
|
Handle := CreateFontIndirect(NCMetrics.lfMenuFont);
|
|
Charset := DEFAULT_CHARSET;
|
|
end
|
|
else
|
|
begin
|
|
Name := 'MS Sans Serif';
|
|
Size := 8;
|
|
Style := [];
|
|
Color := clBtnText;
|
|
end;
|
|
end;
|
|
end;
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
begin
|
|
ParentFont := False;
|
|
with Font do
|
|
begin
|
|
Name := 'Helvetica';
|
|
Height := 11;
|
|
Style := [];
|
|
Color := clBtnText;
|
|
end;
|
|
end;
|
|
{$ENDIF VisualCLX}
|
|
|
|
procedure TJvSpeedBar.VisibleChanged;
|
|
begin
|
|
inherited VisibleChanged;
|
|
if not (csLoading in ComponentState) then
|
|
ForEachItem(SetItemVisible, 0);
|
|
if Assigned(FOnVisibleChanged) then
|
|
FOnVisibleChanged(Self);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.EnabledChanged;
|
|
begin
|
|
inherited EnabledChanged;
|
|
if not ((csLoading in ComponentState) or (csDesigning in ComponentState)) then
|
|
ForEachItem(SetItemEnabled, 0);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.WallpaperChanged(Sender: TObject);
|
|
begin
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetWallpaper(Value: TPicture);
|
|
begin
|
|
FWallpaper.Assign(Value);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.ClearSections;
|
|
begin
|
|
while FSections.Count > 0 do
|
|
RemoveSection(FSections.Count - 1);
|
|
FSections.Clear;
|
|
end;
|
|
|
|
function TJvSpeedBar.Items(Section, Index: Integer): TJvSpeedItem;
|
|
var
|
|
List: TJvSpeedBarSection;
|
|
begin
|
|
Result := nil;
|
|
if (Section >= 0) and (Section < FSections.Count) then
|
|
begin
|
|
List := Sections[Section];
|
|
if List <> nil then
|
|
if (Index >= 0) and (Index < List.Count) then
|
|
Result := List[Index];
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedBar.ItemsCount(Section: Integer): Integer;
|
|
begin
|
|
Result := 0;
|
|
if (Section >= 0) and (Section < FSections.Count) then
|
|
begin
|
|
if FSections[Section] <> nil then
|
|
Result := Sections[Section].Count;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.RemoveSection(Section: Integer);
|
|
var
|
|
Sect: TJvSpeedBarSection;
|
|
Item: TJvSpeedItem;
|
|
begin
|
|
Sect := Sections[Section];
|
|
if Sect <> nil then
|
|
begin
|
|
while Sect.Count > 0 do
|
|
begin
|
|
Item := Sect[0];
|
|
Item.Free;
|
|
end;
|
|
Sect.FParent := nil;
|
|
Sect.Free;
|
|
FSections[Section] := nil;
|
|
end;
|
|
FSections.Delete(Section);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.DeleteSection(Section: Integer);
|
|
var
|
|
Sect: TJvSpeedBarSection;
|
|
I: Integer;
|
|
begin
|
|
Sect := Sections[Section];
|
|
if Sect <> nil then
|
|
begin
|
|
for I := Sect.Count - 1 downto 0 do
|
|
RemoveItem(TJvSpeedItem(Sect[I]));
|
|
Sect.FParent := nil;
|
|
FSections[Section] := nil;
|
|
end;
|
|
FSections.Delete(Section);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.RemoveItem(Item: TJvSpeedItem);
|
|
var
|
|
I, Index: Integer;
|
|
begin
|
|
if FindItem(Item, I, Index) then
|
|
begin
|
|
Item.FButton.Parent := nil;
|
|
Item.FParent := nil;
|
|
Item.FSection := -1;
|
|
Sections[I].FList.Delete(Index);
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedBar.SearchSection(const ACaption: string): Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := -1;
|
|
for I := 0 to FSections.Count - 1 do
|
|
if Sections[I].Caption = ACaption then
|
|
begin
|
|
Result := I;
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedBar.AppendSection(Value: TJvSpeedBarSection): Integer;
|
|
var
|
|
UniqueName: string;
|
|
I: Integer;
|
|
begin
|
|
I := 0;
|
|
UniqueName := Value.Caption;
|
|
while SearchSection(UniqueName) >= 0 do
|
|
begin
|
|
Inc(I);
|
|
UniqueName := Value.Caption + Format(' (%d)', [I]);
|
|
end;
|
|
Value.Caption := UniqueName;
|
|
Result := FSections.Add(Value);
|
|
if Result >= 0 then
|
|
begin
|
|
Value.FParent := Self;
|
|
for I := 0 to Value.Count - 1 do
|
|
begin
|
|
Value[I].FSection := Result;
|
|
SetItemParams(Value[I], not (csLoading in ComponentState));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedBar.AddSection(const ACaption: string): Integer;
|
|
var
|
|
Section: TJvSpeedBarSection;
|
|
begin
|
|
if Owner <> nil then
|
|
Section := TJvSpeedBarSection.Create(Owner)
|
|
else
|
|
Section := TJvSpeedBarSection.Create(Self);
|
|
Section.Caption := ACaption;
|
|
Result := AppendSection(Section);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetItemParams(Item: TJvSpeedItem; InitBounds: Boolean);
|
|
begin
|
|
with Item do
|
|
begin
|
|
FParent := Self;
|
|
with FButton do
|
|
begin
|
|
if InitBounds then
|
|
SetBounds(0, 0, BtnWidth, BtnHeight);
|
|
Style := FButtonStyle;
|
|
Flat := (sbFlatBtns in Options);
|
|
Transparent := (sbTransparentBtns in Options);
|
|
GrayedInactive := (sbGrayedBtns in Options);
|
|
end;
|
|
SetEditing(FEditWin <> NullHandle);
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedBar.NewItem(AOwner: TComponent; Section: Integer;
|
|
const AName: string): TJvSpeedItem;
|
|
begin
|
|
Result := nil;
|
|
if (Section >= 0) and (Section < FSections.Count) then
|
|
begin
|
|
Result := TJvSpeedItem.Create(AOwner);
|
|
try
|
|
Sections[Section].FList.Add(Result);
|
|
Result.FSection := Section;
|
|
SetItemParams(Result, True);
|
|
if AName <> '' then
|
|
with Result do
|
|
begin
|
|
Name := AName;
|
|
Caption := AName;
|
|
FButton.Visible := False;
|
|
FButton.Parent := Self;
|
|
end;
|
|
except
|
|
Result.Free;
|
|
raise;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.AddItem(Section: Integer; Item: TJvSpeedItem);
|
|
var
|
|
I, Index: Integer;
|
|
begin
|
|
if FindItem(Item, I, Index) then
|
|
begin
|
|
Sections[I].FList.Delete(Index);
|
|
if Section >= FSections.Count then
|
|
Section := FSections.Count - 1;
|
|
Sections[Section].FList.Add(Item);
|
|
Item.FSection := Section;
|
|
Exit;
|
|
end;
|
|
if (Section >= 0) and (Item <> nil) then
|
|
begin
|
|
if Assigned(FOnAddItem) then
|
|
begin
|
|
FOnAddItem(Item);
|
|
Section := Item.FSection;
|
|
end;
|
|
if FSections.Count = 0 then
|
|
Section := AddSection('')
|
|
else
|
|
if Section >= FSections.Count then
|
|
Section := FSections.Count - 1;
|
|
Sections[Section].FList.Add(Item);
|
|
Item.FSection := Section;
|
|
SetItemParams(Item, not (csLoading in ComponentState));
|
|
Item.FButton.Visible := False;
|
|
Item.FButton.Parent := Self;
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedBar.FindItem(Item: TJvSpeedItem; var Section,
|
|
Index: Integer): Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := False;
|
|
Section := -1;
|
|
for I := 0 to FSections.Count - 1 do
|
|
if FSections[I] <> nil then
|
|
begin
|
|
Index := Sections[I].FList.IndexOf(Item);
|
|
if Index >= 0 then
|
|
begin
|
|
Section := I;
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.AlignItemsToGrid;
|
|
begin
|
|
ForEachItem(AlignItemToGrid, 0);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.AlignItemToGrid(Item: TJvSpeedItem; Data: Longint);
|
|
begin
|
|
if Item.Visible then
|
|
begin
|
|
if GetOrientation = boVertical then
|
|
begin
|
|
Item.Left := Trunc((Item.Left - FOffset.X) / FGridSize.X) * FGridSize.X + FOffset.X;
|
|
Item.Top := Round((Item.Top - FOffset.Y) / FGridSize.Y) * FGridSize.Y + FOffset.Y;
|
|
end
|
|
else
|
|
begin
|
|
Item.Left := Round((Item.Left - FOffset.X) / FGridSize.X) * FGridSize.X + FOffset.X;
|
|
Item.Top := Trunc((Item.Top - FOffset.Y) / FGridSize.Y) * FGridSize.Y + FOffset.Y;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedBar.AcceptDropItem(Item: TJvSpeedItem; X, Y: Integer): Boolean;
|
|
var
|
|
I, Sect: Integer;
|
|
begin
|
|
Result := False;
|
|
if FindItem(Item, Sect, I) then
|
|
begin
|
|
if GetOrientation = boVertical then
|
|
begin
|
|
X := Trunc((X - FOffset.X) / FGridSize.X) * FGridSize.X + FOffset.X;
|
|
Y := Round((Y - FOffset.Y) / FGridSize.Y) * FGridSize.Y + FOffset.Y;
|
|
end
|
|
else
|
|
begin
|
|
X := Round((X - FOffset.X) / FGridSize.X) * FGridSize.X + FOffset.X;
|
|
Y := Trunc((Y - FOffset.Y) / FGridSize.Y) * FGridSize.Y + FOffset.Y;
|
|
end;
|
|
Item.Left := X;
|
|
Item.Top := Y;
|
|
Result := PtInRect(ClientRect, Point(X, Y));
|
|
if Result then
|
|
Item.FButton.BringToFront
|
|
else
|
|
Item.FButton.SendToBack;
|
|
Item.Visible := Result;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetItemEditing(Item: TJvSpeedItem; Data: Longint);
|
|
begin
|
|
Item.SetEditing(FEditWin <> NullHandle);
|
|
end;
|
|
|
|
function TJvSpeedBar.GetEditing: Boolean;
|
|
begin
|
|
Result := (FEditWin <> NullHandle);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetEditing(Win: THandle);
|
|
begin
|
|
FEditWin := Win;
|
|
ForEachItem(SetItemEditing, 0);
|
|
if (FEditWin = NullHandle) and not (csDesigning in ComponentState) then
|
|
AfterCustomize;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.Paint;
|
|
var
|
|
XCnt, YCnt, X, Y: Integer;
|
|
BevelSize, SaveIndex: Integer;
|
|
Rect: TRect;
|
|
C1, C2: TColor;
|
|
|
|
procedure BevelLine(C: TColor; X1, Y1, X2, Y2: Integer);
|
|
begin
|
|
with Canvas do
|
|
begin
|
|
Pen.Color := C;
|
|
MoveTo(X1, Y1);
|
|
LineTo(X2, Y2);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if not FLocked then
|
|
begin
|
|
Rect := ClientRect;
|
|
BevelSize := BorderWidth;
|
|
if BevelOuter <> bvNone then
|
|
Inc(BevelSize, BevelWidth);
|
|
if BevelInner <> bvNone then
|
|
Inc(BevelSize, BevelWidth);
|
|
InflateRect(Rect, -BevelSize, -BevelSize);
|
|
inherited Paint;
|
|
Canvas.Brush.Color := Color;
|
|
{$IFDEF JVCLThemesEnabled}
|
|
if ThemeServices.ThemesEnabled and ParentBackground then
|
|
begin
|
|
Canvas.Brush.Color := Parent.Brush.Color;
|
|
DrawThemedBackground(Self, Canvas, Rect);
|
|
end
|
|
else
|
|
{$ENDIF JVCLThemesEnabled}
|
|
Canvas.FillRect(Rect);
|
|
if (FWallpaper.Graphic <> nil) and (FWallpaper.Width > 0) and
|
|
(FWallpaper.Height > 0) then
|
|
begin
|
|
SaveIndex := SaveDC(Canvas.Handle);
|
|
try
|
|
with Rect do
|
|
IntersectClipRect(Canvas.Handle, Left, Top, Right - Left +
|
|
BevelSize, Bottom - Top + BevelSize);
|
|
if sbStretchBitmap in Options then
|
|
Canvas.StretchDraw(Rect, FWallpaper.Graphic)
|
|
else
|
|
begin
|
|
XCnt := (ClientWidth - 2 * BevelSize) div FWallpaper.Width;
|
|
YCnt := (ClientHeight - 2 * BevelSize) div FWallpaper.Height;
|
|
for X := 0 to XCnt do
|
|
for Y := 0 to YCnt do
|
|
Canvas.Draw(Rect.Left + X * FWallpaper.Width,
|
|
Rect.Top + Y * FWallpaper.Height, FWallpaper.Graphic);
|
|
end;
|
|
finally
|
|
RestoreDC(Canvas.Handle, SaveIndex);
|
|
end;
|
|
end;
|
|
if FBoundLines <> [] then
|
|
begin
|
|
C1 := clBtnShadow;
|
|
C2 := clBtnHighlight;
|
|
if blTop in FBoundLines then
|
|
begin
|
|
BevelLine(C1, Rect.Left, Rect.Top, Rect.Right, Rect.Top);
|
|
BevelLine(C2, Rect.Left, Rect.Top + 1, Rect.Right, Rect.Top + 1);
|
|
end;
|
|
if blLeft in FBoundLines then
|
|
begin
|
|
BevelLine(C1, Rect.Left, Rect.Top, Rect.Left, Rect.Bottom);
|
|
BevelLine(C2, Rect.Left + 1, Rect.Top + Ord(blTop in FBoundLines), Rect.Left + 1, Rect.Bottom);
|
|
end;
|
|
if blBottom in FBoundLines then
|
|
begin
|
|
BevelLine(C1, Rect.Left, Rect.Bottom - 2, Rect.Right, Rect.Bottom - 2);
|
|
BevelLine(C2, Rect.Left, Rect.Bottom - 1, Rect.Right, Rect.Bottom - 1);
|
|
end;
|
|
if blRight in FBoundLines then
|
|
begin
|
|
BevelLine(C1, Rect.Right - 2, Rect.Top, Rect.Right - 2, Rect.Bottom - Ord(blBottom in FBoundLines));
|
|
BevelLine(C2, Rect.Right - 1, Rect.Top, Rect.Right - 1, Rect.Bottom);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.ApplyOrientation(Value: TBarOrientation);
|
|
begin
|
|
if (GetOrientation <> Value) and not (csReading in ComponentState) then
|
|
begin
|
|
FLocked := True;
|
|
try
|
|
FOrientation := Value;
|
|
SwapInt(Integer(FButtonSize.X), Integer(FButtonSize.Y));
|
|
SwapInt(Integer(FGridSize.X), Integer(FGridSize.Y));
|
|
SwapInt(Integer(FOffset.X), Integer(FOffset.Y));
|
|
ForEachItem(SwapItemBounds, 0);
|
|
finally
|
|
FLocked := False;
|
|
Invalidate;
|
|
end;
|
|
if FEditWin <> NullHandle then
|
|
SendMessage(FEditWin, CM_SPEEDBARCHANGED, SBR_BTNSIZECHANGED, Longint(Self));
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetOrientation(Value: TBarOrientation);
|
|
begin
|
|
if GetOrientation <> Value then
|
|
begin
|
|
if FPosition = bpAuto then
|
|
raise EJvSpeedbarError.CreateRes(@RsEAutoSpeedbarMode);
|
|
ApplyOrientation(Value);
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedBar.GetOrientation: TBarOrientation;
|
|
begin
|
|
if FPosition = bpCustom then
|
|
Result := FOrientation
|
|
else
|
|
case Align of
|
|
alLeft, alRight:
|
|
Result := boVertical;
|
|
alTop, alBottom:
|
|
Result := boHorizontal;
|
|
else
|
|
Result := FOrientation;
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedBar.GetAlign: TAlign;
|
|
begin
|
|
Result := FAlign;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetAlign(Value: TAlign);
|
|
var
|
|
X, Y: Integer;
|
|
begin
|
|
{ fix previous version error }
|
|
if (csLoading in ComponentState) and (Value = alNone) and
|
|
(Position = bpAuto) then
|
|
FFix := True;
|
|
if Align <> Value then
|
|
begin
|
|
X := Width;
|
|
Y := Height;
|
|
if (FPosition = bpAuto) and (Value in [alClient, alNone]) then
|
|
raise EJvSpeedbarError.CreateRes(@RsEAutoSpeedbarMode);
|
|
inherited Align := Value;
|
|
if csLoading in ComponentState then
|
|
begin
|
|
Width := X;
|
|
Height := Y;
|
|
end;
|
|
if FPosition = bpAuto then
|
|
case Value of
|
|
alLeft, alRight:
|
|
ApplyOrientation(boVertical);
|
|
alTop, alBottom:
|
|
ApplyOrientation(boHorizontal);
|
|
else
|
|
if not (csLoading in ComponentState) then
|
|
raise EJvSpeedbarError.CreateRes(@RsEAutoSpeedbarMode);
|
|
end;
|
|
FAlign := inherited Align;
|
|
end;
|
|
end;
|
|
{$IFDEF VisualCLX}
|
|
procedure TJvSpeedBar.ChangeScale(M, D, MH, DH: Integer);
|
|
{$ENDIF VisualCLX}
|
|
{$IFDEF VCL}
|
|
procedure TJvSpeedBar.ChangeScale(M, D: Integer);
|
|
{$ENDIF VCL}
|
|
var
|
|
Flags: TSbScaleFlags;
|
|
begin
|
|
DisableAlign;
|
|
try
|
|
if csLoading in ComponentState then
|
|
Flags := ScaleFlags
|
|
else
|
|
Flags := [sfOffsetX, sfOffsetY, sfBtnSizeX, sfBtnSizeY];
|
|
{$IFDEF VCL}
|
|
if (sfBtnSizeX in Flags) and not (csFixedWidth in ControlStyle) then
|
|
FButtonSize.X := MulDiv(FButtonSize.X, M, D);
|
|
if sfOffsetX in Flags then
|
|
FOffset.X := MulDiv(FOffset.X, M, D);
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
if (sfBtnSizeX in Flags) and not (csFixedWidth in ControlStyle) then
|
|
FButtonSize.X := MulDiv(FButtonSize.X, MH, DH);
|
|
if sfOffsetX in Flags then
|
|
FOffset.X := MulDiv(FOffset.X, MH, DH);
|
|
{$ENDIF VisualCLX}
|
|
if (sfBtnSizeY in Flags) and not (csFixedHeight in ControlStyle) then
|
|
FButtonSize.Y := MulDiv(FButtonSize.Y, M, D);
|
|
if sfOffsetY in Flags then
|
|
FOffset.Y := MulDiv(FOffset.Y, M, D);
|
|
UpdateGridSize;
|
|
inherited ChangeScale(M, D {$IFDEF VisualCLX}, MH, DH {$ENDIF});
|
|
ApplyButtonSize;
|
|
AlignItemsToGrid;
|
|
FScaleFlags := [];
|
|
finally
|
|
EnableAlign;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.AlignControls(AControl: TControl; var Rect: TRect);
|
|
var
|
|
P: TPoint;
|
|
Min: Integer;
|
|
begin
|
|
if FBoundLines <> [] then
|
|
begin
|
|
if blTop in FBoundLines then
|
|
Inc(Rect.Top, 2);
|
|
if blBottom in FBoundLines then
|
|
Dec(Rect.Bottom, 2);
|
|
if blLeft in FBoundLines then
|
|
Inc(Rect.Left, 2);
|
|
if blRight in FBoundLines then
|
|
Dec(Rect.Right, 2);
|
|
end;
|
|
inherited AlignControls(AControl, Rect);
|
|
Min := MinButtonsOffset;
|
|
if FOffset.X < Min then
|
|
begin
|
|
P.X := Min - FOffset.X;
|
|
FOffset.X := Min;
|
|
end
|
|
else
|
|
P.X := 0;
|
|
if FOffset.Y < Min then
|
|
begin
|
|
P.Y := Min - FOffset.Y;
|
|
FOffset.Y := Min;
|
|
end
|
|
else
|
|
P.Y := 0;
|
|
if not (csLoading in ComponentState) and ((P.X <> 0) or (P.Y <> 0)) then
|
|
ForEachItem(OffsetItem, Longint(@P));
|
|
end;
|
|
|
|
procedure TJvSpeedBar.FlatItem(Item: TJvSpeedItem; Data: Longint);
|
|
begin
|
|
Item.FButton.Flat := Boolean(Data);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.GrayedItem(Item: TJvSpeedItem; Data: Longint);
|
|
begin
|
|
Item.FButton.GrayedInactive := Boolean(Data);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.TransparentItem(Item: TJvSpeedItem; Data: Longint);
|
|
begin
|
|
Item.FButton.Transparent := Boolean(Data);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetBoundLines(Value: TBoundLines);
|
|
begin
|
|
if FBoundLines <> Value then
|
|
begin
|
|
FBoundLines := Value;
|
|
Realign;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetOptions(Value: TJvSpeedBarOptions);
|
|
var
|
|
FlatChanged: Boolean;
|
|
begin
|
|
if FOptions <> Value then
|
|
begin
|
|
FlatChanged := (sbFlatBtns in FOptions) <> (sbFlatBtns in Value);
|
|
FOptions := Value;
|
|
ForEachItem(FlatItem, Longint(sbFlatBtns in Options));
|
|
ForEachItem(TransparentItem, Longint(sbTransparentBtns in Options));
|
|
ForEachItem(GrayedItem, Longint(sbGrayedBtns in Options));
|
|
UpdateGridSize;
|
|
if FlatChanged then
|
|
Realign;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.OffsetItem(Item: TJvSpeedItem; Data: Longint);
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
P := PPoint(Data)^;
|
|
Item.FButton.SetBounds(Item.Left + P.X, Item.Top + P.Y, FButtonSize.X,
|
|
FButtonSize.Y);
|
|
end;
|
|
|
|
function TJvSpeedBar.GetButtonsOffset(Index: Integer): Integer;
|
|
begin
|
|
if Index = 0 then
|
|
Result := FOffset.X
|
|
else
|
|
if Index = 1 then
|
|
Result := FOffset.Y
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetButtonsOffset(Index: Integer; Value: Integer);
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
if Value < MinButtonsOffset then
|
|
Value := MinButtonsOffset;
|
|
P.X := 0;
|
|
P.Y := 0;
|
|
if Index = 0 then
|
|
begin
|
|
P.X := Value - FOffset.X;
|
|
FOffset.X := Value;
|
|
Include(FScaleFlags, sfOffsetX);
|
|
end
|
|
else
|
|
if Index = 1 then
|
|
begin
|
|
P.Y := Value - FOffset.Y;
|
|
FOffset.Y := Value;
|
|
Include(FScaleFlags, sfOffsetY);
|
|
end;
|
|
if (P.X <> 0) or (P.Y <> 0) then
|
|
ForEachItem(OffsetItem, Longint(@P));
|
|
end;
|
|
|
|
procedure TJvSpeedBar.UpdateGridSize;
|
|
var
|
|
Base: Integer;
|
|
begin
|
|
case Orientation of
|
|
boHorizontal:
|
|
Base := FButtonSize.X;
|
|
else {boVertical:}
|
|
Base := FButtonSize.Y;
|
|
end;
|
|
case Orientation of
|
|
boHorizontal:
|
|
begin
|
|
FGridSize.X := Max(1, Min(8, Base div 3));
|
|
while Base mod FGridSize.X <> 0 do
|
|
Inc(FGridSize.X);
|
|
if (FGridSize.X = Base) and (Base > 1) then
|
|
begin
|
|
Dec(FGridSize.X);
|
|
while (FGridSize.X > 1) and (Base mod FGridSize.X <> 0) do
|
|
Dec(FGridSize.X);
|
|
end;
|
|
FGridSize.Y := FButtonSize.Y;
|
|
end;
|
|
boVertical:
|
|
begin
|
|
FGridSize.Y := Max(1, Min(8, Base div 3));
|
|
while (Base mod FGridSize.Y <> 0) do
|
|
Inc(FGridSize.Y);
|
|
if (FGridSize.Y = Base) and (Base > 1) then
|
|
begin
|
|
Dec(FGridSize.Y);
|
|
while (FGridSize.Y > 1) and (Base mod FGridSize.Y <> 0) do
|
|
Dec(FGridSize.Y);
|
|
end;
|
|
FGridSize.X := FButtonSize.X;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.ApplyItemSize(Item: TJvSpeedItem; Data: Longint);
|
|
begin
|
|
with Item do
|
|
FButton.SetBounds(FButton.Left, FButton.Top, FButtonSize.X, FButtonSize.Y);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.ApplyButtonSize;
|
|
begin
|
|
ForEachItem(ApplyItemSize, 0);
|
|
if FEditWin <> NullHandle then { update SpeedBar editor }
|
|
SendMessage(FEditWin, CM_SPEEDBARCHANGED, SBR_BTNSIZECHANGED, Longint(Self));
|
|
end;
|
|
|
|
function TJvSpeedBar.GetButtonSize(Index: Integer): Integer;
|
|
begin
|
|
if Index = 0 then
|
|
Result := FButtonSize.X
|
|
else
|
|
if Index = 1 then
|
|
Result := FButtonSize.Y
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetButtonSize(Index, Value: Integer);
|
|
var
|
|
NewSize: TPoint;
|
|
begin
|
|
NewSize.X := FButtonSize.X;
|
|
NewSize.Y := FButtonSize.Y;
|
|
if Index = 0 then
|
|
begin
|
|
NewSize.X := Value;
|
|
Include(FScaleFlags, sfBtnSizeX);
|
|
end
|
|
else
|
|
if Index = 1 then
|
|
begin
|
|
NewSize.Y := Value;
|
|
Include(FScaleFlags, sfBtnSizeY);
|
|
end
|
|
else
|
|
Exit;
|
|
FButtonSize := NewSize;
|
|
UpdateGridSize;
|
|
if not (csReading in ComponentState) then
|
|
case Orientation of
|
|
boHorizontal:
|
|
ClientHeight := Max(ClientHeight, 2 * FOffset.Y + FButtonSize.Y);
|
|
boVertical:
|
|
ClientWidth := Max(ClientWidth, 2 * FOffset.X + FButtonSize.X);
|
|
end;
|
|
ApplyButtonSize;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.GetChildren(Proc: TGetChildProc ; Root: TComponent);
|
|
var
|
|
I, Idx: Integer;
|
|
Sect: TJvSpeedBarSection;
|
|
Item: TJvSpeedItem;
|
|
begin
|
|
inherited GetChildren(Proc, Root);
|
|
for I := 0 to FSections.Count - 1 do
|
|
begin
|
|
Sect := Sections[I];
|
|
if Sect <> nil then
|
|
Proc(Sect);
|
|
end;
|
|
for I := 0 to FSections.Count - 1 do
|
|
begin
|
|
Sect := Sections[I];
|
|
if Sect <> nil then
|
|
for Idx := 0 to Sect.Count - 1 do
|
|
begin
|
|
Item := Sect[Idx];
|
|
if (Item <> nil) and (Item.Owner <> Self) then
|
|
Proc(Item);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetChildOrder(Component: TComponent; Order: Integer);
|
|
begin
|
|
if FSections.IndexOf(Component) >= 0 then
|
|
(Component as TJvSpeedBarSection).Index := Order;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.Notification(AComponent: TComponent;
|
|
Operation: TOperation);
|
|
begin
|
|
inherited Notification(AComponent, Operation);
|
|
if Operation = opRemove then
|
|
if AComponent = FImages then
|
|
SetImages(nil);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.InvalidateItem(Item: TJvSpeedItem; Data: Longint);
|
|
begin
|
|
with Item do
|
|
if Button <> nil then
|
|
begin
|
|
TJvSpeedBarButton(Button).InvalidateGlyph;
|
|
if FImageIndex >= 0 then
|
|
Button.Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.ImageListChange(Sender: TObject);
|
|
begin
|
|
ForEachItem(InvalidateItem, 0);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetImages(Value: TCustomImageList);
|
|
begin
|
|
if Images <> nil then
|
|
Images.UnRegisterChanges(FImageChangeLink);
|
|
FImages := Value;
|
|
if FImages <> nil then
|
|
begin
|
|
FImages.RegisterChanges(FImageChangeLink);
|
|
FImages.FreeNotification(Self);
|
|
end;
|
|
ImageListChange(FImages);
|
|
end;
|
|
|
|
function TJvSpeedBar.SearchItem(const ItemName: string): TJvSpeedItem;
|
|
var
|
|
I, Idx: Integer;
|
|
Sect: TJvSpeedBarSection;
|
|
Item: TJvSpeedItem;
|
|
begin
|
|
Result := nil;
|
|
for I := 0 to FSections.Count - 1 do
|
|
if FSections[I] <> nil then
|
|
begin
|
|
Sect := TJvSpeedBarSection(FSections[I]);
|
|
for Idx := 0 to Sect.Count - 1 do
|
|
if Sect[Idx] <> nil then
|
|
begin
|
|
Item := TJvSpeedItem(Sect[Idx]);
|
|
if AnsiSameText(Item.Name, ItemName) then
|
|
begin
|
|
Result := Item;
|
|
Break;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
type
|
|
TJvSpeedBarPos = (bpTop, bpBottom, bpLeft, bpRight);
|
|
|
|
const
|
|
PosToAlign: array [TJvSpeedBarPos] of TAlign = (alTop, alBottom, alLeft, alRight);
|
|
|
|
function TJvSpeedBar.GetFramePos(X, Y: Integer; var Apply: Boolean): Integer;
|
|
var
|
|
P: TPoint;
|
|
W, H: Double;
|
|
begin
|
|
P := Parent.ScreenToClient(ClientToScreen(Point(X, Y)));
|
|
W := Parent.ClientWidth;
|
|
H := Parent.ClientHeight;
|
|
if P.Y <= P.X * (H / W) then
|
|
begin { top or right }
|
|
if P.Y >= H * (1 - P.X / W) then
|
|
Result := Ord(bpRight)
|
|
else
|
|
Result := Ord(bpTop);
|
|
end
|
|
else
|
|
begin { left or bottom }
|
|
if P.Y >= H * (1 - P.X / W) then
|
|
Result := Ord(bpBottom)
|
|
else
|
|
Result := Ord(bpLeft);
|
|
end;
|
|
if Assigned(FOnApplyAlign) then
|
|
FOnApplyAlign(Self, PosToAlign[TJvSpeedBarPos(Result)], Apply);
|
|
end;
|
|
|
|
function TJvSpeedBar.GetFrameRect(X, Y: Integer): TRect;
|
|
var
|
|
Pos: TJvSpeedBarPos;
|
|
W: Integer;
|
|
Apply: Boolean;
|
|
|
|
function InsertBefore(C1, C2: TControl; AAlign: TAlign): Boolean;
|
|
begin
|
|
Result := False;
|
|
case AAlign of
|
|
alTop:
|
|
Result := C1.Top < C2.Top;
|
|
alBottom:
|
|
Result := (C1.Top + C1.Height) > (C2.Top + C2.Height);
|
|
alLeft:
|
|
Result := C1.Left < C2.Left;
|
|
alRight:
|
|
Result := (C1.Left + C1.Width) > (C2.Left + C2.Width);
|
|
end;
|
|
end;
|
|
|
|
function MaxRect: TRect;
|
|
var
|
|
I: Integer;
|
|
Control: TControl;
|
|
begin
|
|
Result := Parent.ClientRect;
|
|
for I := 0 to Parent.ControlCount - 1 do
|
|
begin
|
|
Control := Parent.Controls[I];
|
|
if (Control.Visible) and (Control <> Self) and not
|
|
(Control.Align in [alNone, alClient]) then
|
|
begin
|
|
if (Control.Align > PosToAlign[Pos]) or ((Control.Align = PosToAlign[Pos]) and
|
|
not InsertBefore(Control, Self, Control.Align)) then
|
|
Continue;
|
|
case Control.Align of
|
|
alTop:
|
|
Inc(Result.Top, Control.Height);
|
|
alBottom:
|
|
Dec(Result.Bottom, Control.Height);
|
|
alLeft:
|
|
Inc(Result.Left, Control.Width);
|
|
alRight:
|
|
Dec(Result.Right, Control.Width);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
Apply := True;
|
|
Pos := TJvSpeedBarPos(GetFramePos(X, Y, Apply));
|
|
if Apply then
|
|
begin
|
|
Result := MaxRect;
|
|
FPrevAlign := PosToAlign[Pos];
|
|
end
|
|
else
|
|
begin
|
|
Result := FPrevRect;
|
|
Exit;
|
|
end;
|
|
with Result do
|
|
begin
|
|
TopLeft := Parent.ClientToScreen(TopLeft);
|
|
BottomRight := Parent.ClientToScreen(BottomRight);
|
|
end;
|
|
case GetOrientation of
|
|
boHorizontal:
|
|
W := Height;
|
|
boVertical:
|
|
W := Width;
|
|
else
|
|
W := 0;
|
|
end;
|
|
case Pos of
|
|
bpTop:
|
|
Result.Bottom := Result.Top + W;
|
|
bpBottom:
|
|
Result.Top := Result.Bottom - W;
|
|
bpLeft:
|
|
Result.Right := Result.Left + W;
|
|
bpRight:
|
|
Result.Left := Result.Right - W;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.StartDragFrame;
|
|
var
|
|
Rect: TRect;
|
|
begin
|
|
with Rect do
|
|
begin
|
|
TopLeft := ClientToScreen(Point(0, 0));
|
|
BottomRight := ClientToScreen(Point(Width, Height));
|
|
end;
|
|
FPrevRect := Rect;
|
|
FPrevAlign := Align;
|
|
DrawInvertFrame(FPrevRect, DragFrameWidth);
|
|
SetCursor(Screen.Cursors[crDragHand]);
|
|
FDrag := True;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.DragFrame(X, Y: Integer);
|
|
var
|
|
Rect: TRect;
|
|
begin
|
|
Rect := GetFrameRect(X, Y);
|
|
if not EqualRect(Rect, FPrevRect) then
|
|
begin
|
|
DrawInvertFrame(FPrevRect, DragFrameWidth);
|
|
SetCursor(Screen.Cursors[crDragHand]);
|
|
FPrevRect := Rect;
|
|
DrawInvertFrame(FPrevRect, DragFrameWidth);
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.StopDragFrame(X, Y: Integer);
|
|
var
|
|
Pos: TJvSpeedBarPos;
|
|
Apply: Boolean;
|
|
begin
|
|
DrawInvertFrame(FPrevRect, DragFrameWidth);
|
|
SetCursor(Screen.Cursors[Cursor]);
|
|
FDrag := False;
|
|
if Align in [alLeft, alTop, alRight, alBottom] then
|
|
begin
|
|
Apply := True;
|
|
Pos := TJvSpeedBarPos(GetFramePos(X, Y, Apply));
|
|
Parent.DisableAlign;
|
|
try
|
|
if Apply then
|
|
Align := PosToAlign[Pos]
|
|
else
|
|
Align := FPrevAlign;
|
|
finally
|
|
Parent.EnableAlign;
|
|
end;
|
|
PosChanged;
|
|
end;
|
|
end;
|
|
|
|
function TJvSpeedBar.CheckResize(Shift: TShiftState; X, Y: Integer): Boolean;
|
|
begin
|
|
Result := False;
|
|
if (FEditWin <> NullHandle) and (sbAllowResize in Options) and not FDrag then
|
|
begin
|
|
if (Align in [alTop, alBottom]) and (X > 0) and (X <= ClientWidth) then
|
|
begin
|
|
case Align of
|
|
alTop:
|
|
Result := (Y > ClientHeight - StartDragOffset) and
|
|
(Y <= ClientHeight + StartDragOffset);
|
|
alBottom:
|
|
Result := (Y > -StartDragOffset) and (Y <= StartDragOffset);
|
|
end;
|
|
if Result then
|
|
SetCursor(Screen.Cursors[crSizeNS]);
|
|
end;
|
|
if (Align in [alLeft, alRight]) and (Y > 0) and (Y <= ClientHeight) then
|
|
begin
|
|
case Align of
|
|
alLeft:
|
|
Result := (X > ClientWidth - StartDragOffset) and
|
|
(X <= ClientWidth + StartDragOffset);
|
|
alRight:
|
|
Result := (X > -StartDragOffset) and (X <= StartDragOffset);
|
|
end;
|
|
if Result then
|
|
SetCursor(Screen.Cursors[crSizeWE]);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
begin
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
if (Button = mbLeft) and (Parent <> nil) and CheckResize(Shift, X, Y) then
|
|
begin
|
|
FResizing := True;
|
|
MouseCapture := True;
|
|
Exit;
|
|
end;
|
|
if (Button = mbLeft) and (Parent <> nil) and (sbAllowDrag in Options) and
|
|
(Align in [alLeft, alTop, alRight, alBottom]) then
|
|
begin
|
|
MouseCapture := True;
|
|
FStartDrag := Point(X, Y);
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.MouseMove(Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
Cnt: Integer;
|
|
P: TPoint;
|
|
begin
|
|
inherited MouseMove(Shift, X, Y);
|
|
CheckResize(Shift, X, Y);
|
|
Cnt := 0;
|
|
if (GetCapture = Handle) and (csLButtonDown in ControlState) then
|
|
if FResizing then
|
|
begin
|
|
P := Parent.ScreenToClient(ClientToScreen(Point(X, Y)));
|
|
if not PtInRectInclusive(Parent.ClientRect,P) then
|
|
Exit;
|
|
case Align of
|
|
alTop:
|
|
Cnt := Abs(Y - (2 * FOffset.Y)) div BtnHeight;
|
|
alLeft:
|
|
Cnt := Abs(X - (2 * FOffset.X)) div BtnWidth;
|
|
alBottom:
|
|
Cnt := Abs(ClientHeight - (2 * FOffset.Y) - Y) div BtnHeight;
|
|
alRight:
|
|
Cnt := Abs(ClientWidth - (2 * FOffset.X) - X) div BtnWidth;
|
|
end;
|
|
Cnt := Max(1, Cnt);
|
|
case Align of
|
|
alTop, alBottom:
|
|
begin
|
|
SetCursor(Screen.Cursors[crSizeNS]);
|
|
Height := Min(BtnHeight * Cnt + (2 * FOffset.Y), Parent.ClientHeight);
|
|
end;
|
|
alLeft, alRight:
|
|
begin
|
|
SetCursor(Screen.Cursors[crSizeWE]);
|
|
Width := Min(BtnWidth * Cnt + (2 * FOffset.X), Parent.ClientWidth);
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
if sbAllowDrag in Options then
|
|
begin
|
|
if FDrag then
|
|
DragFrame(X, Y)
|
|
else
|
|
begin
|
|
if (Abs(X - FStartDrag.X) > StartDragOffset) or
|
|
(Abs(Y - FStartDrag.Y) > StartDragOffset) then
|
|
StartDragFrame;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
begin
|
|
if Button = mbLeft then
|
|
begin
|
|
if FResizing then
|
|
begin
|
|
FResizing := False;
|
|
SetCursor(Screen.Cursors[Cursor]);
|
|
end;
|
|
if FDrag then
|
|
StopDragFrame(X, Y);
|
|
MouseCapture := False;
|
|
end;
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.PosChanged;
|
|
begin
|
|
if Assigned(FOnPosChanged) then
|
|
FOnPosChanged(Self);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.AfterCustomize;
|
|
begin
|
|
if Assigned(FOnCustomize) then
|
|
FOnCustomize(Self);
|
|
end;
|
|
|
|
function TJvSpeedBar.GetStorage: TJvFormPlacement;
|
|
begin
|
|
Result := FIniLink.Storage;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SetStorage(Value: TJvFormPlacement);
|
|
begin
|
|
FIniLink.Storage := Value;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.Customize(HelpCtx: THelpContext);
|
|
begin
|
|
ShowSpeedbarSetupWindow(Self, HelpCtx);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.IniSave(Sender: TObject);
|
|
begin
|
|
if (Name <> '') and IniStorage.IsActive then
|
|
SaveToAppStorage(IniStorage.AppStorage, IniStorage.AppStorage.ConcatPaths([
|
|
IniStorage.AppStoragePath, GetDefaultSection(Self)]));
|
|
end;
|
|
|
|
procedure TJvSpeedBar.IniLoad(Sender: TObject);
|
|
begin
|
|
if (Name <> '') and IniStorage.IsActive then
|
|
LoadFromAppStorage(IniStorage.AppStorage, IniStorage.AppStorage.ConcatPaths([
|
|
IniStorage.AppStoragePath, GetDefaultSection(Self)]));
|
|
end;
|
|
|
|
const
|
|
{ The following strings should not be localized }
|
|
sPosition = 'Position';
|
|
sCount = 'Count';
|
|
sBtn = 'Button';
|
|
sVer = 'Version';
|
|
sPixelsPerInch = 'PixelsPerInch';
|
|
sBtnWidth = 'BtnWidth';
|
|
sBtnHeight = 'BtnHeight';
|
|
sBarWidth = 'Width';
|
|
|
|
type
|
|
PIniData = ^TIniData;
|
|
TIniData = record
|
|
AppStorage: TJvCustomAppStorage;
|
|
I: Integer;
|
|
Path: string;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.HideItem(Item: TJvSpeedItem; Data: Longint);
|
|
begin
|
|
Item.Visible := False;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.WriteItemLayout(Item: TJvSpeedItem; Data: Longint);
|
|
begin
|
|
if Item.Visible and Item.Stored then
|
|
begin
|
|
Inc(PIniData(Data)^.I);
|
|
with PIniData(Data)^ do
|
|
AppStorage.WriteString(AppStorage.ConcatPaths([Path, sBtn + IntToStr(I)]),
|
|
Format('%s,%d,%d', [Item.Name, Item.Left, Item.Top]));
|
|
end;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SaveLayout;
|
|
begin
|
|
Save;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.RestoreLayout;
|
|
begin
|
|
Load;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.LoadFromAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
|
|
const
|
|
Delims = [' ', ','];
|
|
var
|
|
Item: TJvSpeedItem;
|
|
Count: Integer;
|
|
I: Integer;
|
|
S: string;
|
|
begin
|
|
FPrevAlign := Align;
|
|
if AppStorage.ReadInteger(AppStorage.ConcatPaths([Path, sVer]), FVersion) < FVersion then
|
|
// (marcelb) shouldn't we raise an exception "Invalid version" here?
|
|
Exit;
|
|
if sbAllowDrag in Options then
|
|
try
|
|
Align := TAlign(AppStorage.ReadInteger(AppStorage.ConcatPaths([Path, sPosition]), Integer(Align)));
|
|
except
|
|
Align := alTop;
|
|
end;
|
|
if Owner is TCustomForm then
|
|
I := TForm(Owner).PixelsPerInch
|
|
else
|
|
I := 0;
|
|
if Screen.PixelsPerInch <> AppStorage.ReadInteger(AppStorage.ConcatPaths([Path, sPixelsPerInch]), I) then
|
|
begin
|
|
if FPrevAlign <> Align then
|
|
PosChanged;
|
|
Exit;
|
|
end;
|
|
if sbAllowResize in Options then
|
|
begin
|
|
if Align in [alTop, alBottom] then
|
|
Height := AppStorage.ReadInteger(AppStorage.ConcatPaths([Path, sBarWidth]), Height)
|
|
else
|
|
if Align in [alLeft, alRight] then
|
|
Width := AppStorage.ReadInteger(AppStorage.ConcatPaths([Path, sBarWidth]), Width);
|
|
end;
|
|
if FPrevAlign <> Align then
|
|
PosChanged;
|
|
{if (AppStorage.ReadInteger(AppStorage.ConcatPaths([Path, sBtnWidth]), FButtonSize.X) >
|
|
FButtonSize.X) or (AppStorage.ReadInteger(AppStorage.ConcatPaths([Path, sBtnHeight]),
|
|
FButtonSize.Y) > FButtonSize.Y) then Exit;}
|
|
Count := AppStorage.ReadInteger(AppStorage.ConcatPaths([Path, sCount]), 0);
|
|
if Count > 0 then
|
|
begin
|
|
ForEachItem(HideItem, 0);
|
|
for I := 1 to Count do
|
|
begin
|
|
S := AppStorage.ReadString(AppStorage.ConcatPaths([Path, sBtn + IntToStr(I)]), '');
|
|
if S <> '' then
|
|
begin
|
|
Item := SearchItem(ExtractWord(1, S, Delims));
|
|
if Item <> nil then
|
|
begin
|
|
Item.Left := Max(StrToIntDef(ExtractWord(2, S, Delims), Item.Left),
|
|
FOffset.X);
|
|
Item.Top := Max(StrToIntDef(ExtractWord(3, S, Delims), Item.Top),
|
|
FOffset.Y);
|
|
Item.Visible := True;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
Repaint;
|
|
end;
|
|
|
|
procedure TJvSpeedBar.SaveToAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
|
|
var
|
|
Data: TIniData;
|
|
begin
|
|
Data.AppStorage := AppStorage;
|
|
Data.Path := Path;
|
|
Data.I := 0;
|
|
AppStorage.DeleteSubTree(Path);
|
|
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, sPosition]), Integer(Align));
|
|
if Align in [alTop, alBottom] then
|
|
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, sBarWidth]), Height)
|
|
else
|
|
if Align in [alLeft, alRight] then
|
|
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, sBarWidth]), Width);
|
|
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, sVer]), FVersion);
|
|
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, sPixelsPerInch]), Screen.PixelsPerInch);
|
|
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, sBtnWidth]), FButtonSize.X);
|
|
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, sBtnHeight]), FButtonSize.Y);
|
|
ForEachItem(WriteItemLayout, Longint(@Data));
|
|
AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, sCount]), Data.I);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.Load;
|
|
begin
|
|
IniLoad(nil);
|
|
end;
|
|
|
|
procedure TJvSpeedBar.Save;
|
|
begin
|
|
IniSave(nil);
|
|
end;
|
|
|
|
//=== { TJvBtnControl } ======================================================
|
|
|
|
constructor TJvBtnControl.Create(AOwner: TComponent);
|
|
begin
|
|
FImage := TJvButtonImage.Create;
|
|
inherited Create(AOwner);
|
|
Cursor := crDragHand;
|
|
FSpacing := 1;
|
|
FMargin := -1;
|
|
FLayout := blGlyphTop;
|
|
FImageIndex := -1;
|
|
end;
|
|
|
|
destructor TJvBtnControl.Destroy;
|
|
begin
|
|
FImage.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{$IFDEF VCL}
|
|
procedure TJvBtnControl.CreateParams(var Params: TCreateParams);
|
|
begin
|
|
inherited CreateParams(Params);
|
|
with Params do
|
|
begin
|
|
Style := WS_POPUP or WS_DISABLED;
|
|
WindowClass.Style := WindowClass.Style or CS_SAVEBITS;
|
|
if NewStyleControls then
|
|
ExStyle := WS_EX_TOOLWINDOW;
|
|
end;
|
|
end;
|
|
{$ENDIF VCL}
|
|
|
|
procedure TJvBtnControl.AssignSpeedItem(Item: TJvSpeedItem);
|
|
begin
|
|
Alignment := Item.FButton.Alignment;
|
|
Glyph := Item.Glyph;
|
|
NumGlyphs := Item.NumGlyphs;
|
|
Spacing := Item.Spacing;
|
|
Margin := Item.Margin;
|
|
Layout := Item.Layout;
|
|
Caption := Item.BtnCaption;
|
|
WordWrap := Item.WordWrap;
|
|
ImageIndex := Item.ImageIndex;
|
|
if Item.SpeedBar <> nil then
|
|
Images := Item.SpeedBar.Images
|
|
else
|
|
Images := nil;
|
|
Font := Item.Font;
|
|
{$IFDEF VCL}
|
|
BiDiMode := Item.FButton.BiDiMode;
|
|
{$ENDIF VCL}
|
|
SetBounds(0, 0, Item.SpeedBar.BtnWidth, Item.SpeedBar.BtnHeight);
|
|
end;
|
|
|
|
function TJvBtnControl.GetGlyph: TBitmap;
|
|
begin
|
|
Result := FImage.Glyph;
|
|
end;
|
|
|
|
function TJvBtnControl.GetNumGlyphs: TJvNumGlyphs;
|
|
begin
|
|
Result := FImage.NumGlyphs;
|
|
end;
|
|
|
|
function TJvBtnControl.GetCaption: TCaption;
|
|
begin
|
|
Result := FImage.Caption;
|
|
end;
|
|
|
|
procedure TJvBtnControl.SetCaption(const Value: TCaption);
|
|
begin
|
|
FImage.Caption := Value;
|
|
end;
|
|
|
|
procedure TJvBtnControl.SetNumGlyphs(Value: TJvNumGlyphs);
|
|
begin
|
|
FImage.NumGlyphs := Value;
|
|
end;
|
|
|
|
procedure TJvBtnControl.SetGlyph(Value: TBitmap);
|
|
begin
|
|
FImage.Glyph := Value;
|
|
end;
|
|
|
|
function TJvBtnControl.GetWordWrap: Boolean;
|
|
begin
|
|
Result := FImage.WordWrap;
|
|
end;
|
|
|
|
procedure TJvBtnControl.SetWordWrap(Value: Boolean);
|
|
begin
|
|
FImage.WordWrap := Value;
|
|
end;
|
|
|
|
function TJvBtnControl.GetAlignment: TAlignment;
|
|
begin
|
|
Result := FImage.Alignment;
|
|
end;
|
|
|
|
procedure TJvBtnControl.SetAlignment(Value: TAlignment);
|
|
begin
|
|
FImage.Alignment := Value;
|
|
end;
|
|
|
|
procedure TJvBtnControl.BoundsChanged;
|
|
begin
|
|
FImage.ButtonSize := Point(ClientWidth, ClientHeight);
|
|
inherited BoundsChanged;
|
|
end;
|
|
|
|
procedure TJvBtnControl.Paint;
|
|
begin
|
|
FImage.DrawEx(Canvas, 0, 0, Margin, Spacing, Layout, Font, Images,
|
|
ImageIndex,
|
|
{$IFDEF VCL}
|
|
DrawTextBiDiModeFlags(Alignments[Alignment])
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
Alignments[Alignment]
|
|
{$ENDIF VisualCLX}
|
|
);
|
|
end;
|
|
|
|
procedure TJvBtnControl.Activate(Rect: TRect);
|
|
begin
|
|
if IsRectEmpty(BoundsRect) then
|
|
BoundsRect := Rect;
|
|
SetWindowPos(Handle, HWND_TOPMOST, Rect.Left, Rect.Top, 0,
|
|
0, SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE);
|
|
SetCursor(Screen.Cursors[Cursor]);
|
|
end;
|
|
|
|
procedure TJvBtnControl.ReleaseHandle;
|
|
begin
|
|
DestroyHandle;
|
|
end;
|
|
|
|
{ Utility routines }
|
|
|
|
function NewSpeedSection(ASpeedBar: TJvSpeedBar; const ACaption: string): Integer;
|
|
begin
|
|
Result := ASpeedBar.AddSection(ACaption);
|
|
end;
|
|
|
|
function NewSpeedItem(AOwner: TComponent; ASpeedBar: TJvSpeedBar; Section: Integer;
|
|
const AName: string): TJvSpeedItem;
|
|
begin
|
|
Result := ASpeedBar.NewItem(AOwner, Section, AName);
|
|
end;
|
|
|
|
function FindSpeedBar(const Pos: TPoint): TJvSpeedBar;
|
|
var
|
|
Window: TWinControl;
|
|
Handle: THandle;
|
|
begin
|
|
Result := nil;
|
|
Handle := WindowFromPoint(Pos);
|
|
Window := nil;
|
|
while (Handle <> NullHandle) and (Window = nil) do
|
|
begin
|
|
Window := FindControl(Handle);
|
|
if Window = nil then
|
|
Handle := GetParent(Handle);
|
|
end;
|
|
if Window <> nil then
|
|
begin
|
|
if Window is TJvSpeedBar then
|
|
Result := Window as TJvSpeedBar;
|
|
end;
|
|
end;
|
|
|
|
procedure DrawCellButton(Grid: TDrawGrid; R: TRect; Item: TJvSpeedItem;
|
|
Image: TJvButtonImage; ARightToLeft: Boolean = False);
|
|
var
|
|
FBar: TJvSpeedBar;
|
|
AFont: TFont;
|
|
ImageList: TCustomImageList;
|
|
begin
|
|
if Item <> nil then
|
|
begin
|
|
FBar := Item.SpeedBar;
|
|
AFont := nil;
|
|
ImageList := nil;
|
|
if FBar <> nil then
|
|
begin
|
|
AFont := FBar.Font;
|
|
if Item.ImageIndex >= 0 then
|
|
ImageList := FBar.Images;
|
|
end;
|
|
if ImageList = nil then
|
|
Image.Glyph := Item.Glyph
|
|
else
|
|
Image.Glyph := nil;
|
|
with Image do
|
|
begin
|
|
Alignment := Item.FButton.Alignment;
|
|
NumGlyphs := Item.NumGlyphs;
|
|
Caption := Item.BtnCaption;
|
|
WordWrap := Item.WordWrap;
|
|
if FBar <> nil then
|
|
ButtonSize := Point(FBar.BtnWidth, FBar.BtnHeight);
|
|
end;
|
|
Image.DrawEx(Grid.Canvas, R.Left + 1, R.Top + 1, Item.Margin,
|
|
Item.Spacing, Item.Layout, AFont, ImageList, Item.ImageIndex,
|
|
{$IFDEF VCL}
|
|
Item.FButton.DrawTextBiDiModeFlags(Alignments[Image.Alignment])
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
Alignments[Image.Alignment]
|
|
{$ENDIF VisualCLX}
|
|
);
|
|
Inc(R.Left, Image.ButtonSize.X + 3);
|
|
DrawCellText(Grid, 0, 0, Item.Caption, R, taLeftJustify, vaCenterJustify, ARightToLeft);
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF UNITVERSIONING}
|
|
initialization
|
|
RegisterUnitVersion(HInstance, UnitVersioning);
|
|
|
|
finalization
|
|
UnregisterUnitVersion(HInstance);
|
|
{$ENDIF UNITVERSIONING}
|
|
|
|
end.
|
|
|