git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@24 05c56307-c608-d34a-929d-697000501d7a
2377 lines
75 KiB
ObjectPascal
2377 lines
75 KiB
ObjectPascal
|
|
{********************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ ExpressEditors }
|
|
{ }
|
|
{ Copyright (c) 1998-2008 Developer Express Inc. }
|
|
{ ALL RIGHTS RESERVED }
|
|
{ }
|
|
{ The entire contents of this file is protected by U.S. and }
|
|
{ International Copyright Laws. Unauthorized reproduction, }
|
|
{ reverse-engineering, and distribution of all or any portion of }
|
|
{ the code contained in this file is strictly prohibited and may }
|
|
{ result in severe civil and criminal penalties and will be }
|
|
{ prosecuted to the maximum extent possible under the law. }
|
|
{ }
|
|
{ RESTRICTIONS }
|
|
{ }
|
|
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
|
|
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
|
|
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
|
|
{ LICENSED TO DISTRIBUTE THE EXPRESSEDITORS AND ALL }
|
|
{ ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
|
|
{ }
|
|
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
|
|
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
|
|
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
|
|
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
|
|
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
|
|
{ }
|
|
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
|
|
{ ADDITIONAL RESTRICTIONS. }
|
|
{ }
|
|
{********************************************************************}
|
|
|
|
unit cxGroupBox;
|
|
|
|
{$I cxVer.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages,
|
|
SysUtils, Classes, Controls, Graphics, Forms, cxControls, cxGraphics,
|
|
cxLookAndFeels, cxContainer, cxEditPaintUtils, cxEdit,
|
|
cxTextEdit, cxClasses, cxCheckBox, cxLookAndFeelPainters;
|
|
|
|
type
|
|
TcxCaptionAlignment = (alTopLeft, alTopCenter, alTopRight,
|
|
alBottomLeft, alBottomCenter, alBottomRight,
|
|
alLeftTop, alLeftCenter, alLeftBottom,
|
|
alRightTop, alRightCenter, alRightBottom,
|
|
alCenterCenter);
|
|
|
|
{ TcxGroupBoxButtonViewInfo }
|
|
|
|
TcxGroupBoxButtonViewInfo = class(TcxEditButtonViewInfo)
|
|
public
|
|
Caption: string;
|
|
Column, Row: Integer;
|
|
function GetGlyphRect(ACanvas: TcxCanvas; AGlyphSize: TSize; AAlignment: TLeftRight; AIsPaintCopy: Boolean): TRect; virtual;
|
|
end;
|
|
|
|
{ TcxGroupBoxViewInfo }
|
|
|
|
TcxCustomGroupBox = class;
|
|
|
|
TcxGroupBoxViewInfo = class(TcxCustomTextEditViewInfo)
|
|
private
|
|
function GetControlRect: TRect;
|
|
function GetEdit: TcxCustomGroupBox;
|
|
procedure InternalDrawByPainter(ACanvas: TcxCanvas;
|
|
APainter: TcxCustomLookAndFeelPainterClass);
|
|
procedure InternalDrawCustom(ACanvas: TcxCanvas);
|
|
protected
|
|
function GetButtonViewInfoClass: TcxEditButtonViewInfoClass; override;
|
|
procedure DrawCaption(ACanvas: TcxCanvas);
|
|
procedure InternalPaint(ACanvas: TcxCanvas); override;
|
|
property ControlRect: TRect read GetControlRect;
|
|
public
|
|
Alignment: TLeftRight;
|
|
CaptionBitmap: TBitmap;
|
|
CaptionBitmapCanvas: TcxCanvas;
|
|
CaptionRect: TRect;
|
|
IsDesigning: Boolean;
|
|
TextRect: TRect;
|
|
constructor Create; override;
|
|
destructor Destroy; override;
|
|
property Edit: TcxCustomGroupBox read GetEdit;
|
|
end;
|
|
|
|
{ TcxGroupBoxViewData }
|
|
|
|
TcxGroupBoxViewData = class(TcxCustomEditViewData)
|
|
private
|
|
function GetCaptionRect(ACanvas: TcxCanvas): TRect;
|
|
function GetEdit: TcxCustomGroupBox;
|
|
procedure CalcRects(ACanvas: TcxCanvas; AEditViewInfo: TcxGroupBoxViewInfo);
|
|
protected
|
|
function GetContainerState(const ABounds: TRect; const P: TPoint;
|
|
Button: TcxMouseButton; Shift: TShiftState;
|
|
AIsMouseEvent: Boolean): TcxContainerState; override;
|
|
public
|
|
procedure Calculate(ACanvas: TcxCanvas; const ABounds: TRect; const P: TPoint;
|
|
Button: TcxMouseButton; Shift: TShiftState; AViewInfo: TcxCustomEditViewInfo;
|
|
AIsMouseEvent: Boolean); override;
|
|
function GetBorderColor: TColor; override;
|
|
function GetBorderExtent: TRect; override;
|
|
function GetClientExtent(ACanvas: TcxCanvas;
|
|
AViewInfo: TcxCustomEditViewInfo): TRect; override;
|
|
function HasShadow: Boolean; override;
|
|
class function IsNativeStyle(ALookAndFeel: TcxLookAndFeel): Boolean; override;
|
|
property Edit: TcxCustomGroupBox read GetEdit;
|
|
end;
|
|
|
|
{ TcxButtonGroupViewData }
|
|
|
|
TcxCustomButtonGroupProperties = class;
|
|
|
|
TcxEditMetrics = record
|
|
AutoHeightColumnWidthCorrection, AutoHeightWidthCorrection,
|
|
ColumnWidthCorrection, WidthCorrection: Integer;
|
|
ClientLeftBoundCorrection, ClientWidthCorrection, ColumnOffset: Integer;
|
|
ButtonSize: TSize;
|
|
end;
|
|
|
|
{ TcxButtonGroupViewInfo }
|
|
|
|
TcxButtonGroupViewInfo = class(TcxGroupBoxViewInfo)
|
|
protected
|
|
procedure DrawEditButton(ACanvas: TcxCanvas; AButtonVisibleIndex: Integer); override;
|
|
procedure DrawButtonCaption(ACanvas: TcxCanvas;
|
|
AButtonViewInfo: TcxGroupBoxButtonViewInfo; const AGlyphRect: TRect); virtual; abstract;
|
|
procedure DrawButtonGlyph(ACanvas: TcxCanvas;
|
|
AButtonViewInfo: TcxGroupBoxButtonViewInfo; const AGlyphRect: TRect); virtual; abstract;
|
|
function GetGlyphSize: TSize; virtual;
|
|
function IsButtonGlypthTransparent(AButtonViewInfo: TcxGroupBoxButtonViewInfo): Boolean; virtual; abstract;
|
|
public
|
|
CaptionExtent: TRect;
|
|
GlyphSize: TSize;
|
|
end;
|
|
|
|
TcxButtonGroupViewData = class(TcxGroupBoxViewData)
|
|
private
|
|
function GetProperties: TcxCustomButtonGroupProperties;
|
|
protected
|
|
procedure CalculateButtonPositions(ACanvas: TcxCanvas;
|
|
AViewInfo: TcxCustomEditViewInfo); virtual;
|
|
procedure CalculateButtonViewInfos(AViewInfo: TcxCustomEditViewInfo); virtual;
|
|
function GetDrawTextFlags: Integer; virtual;
|
|
procedure GetEditMetrics(AAutoHeight: Boolean; ACanvas: TcxCanvas;
|
|
out AMetrics: TcxEditMetrics); virtual; abstract;
|
|
function GetCaptionRectExtent: TRect; virtual;
|
|
procedure CalculateButtonNativeState(AViewInfo: TcxCustomEditViewInfo;
|
|
AButtonViewInfo: TcxGroupBoxButtonViewInfo); virtual; abstract;
|
|
public
|
|
procedure Calculate(ACanvas: TcxCanvas; const ABounds: TRect; const P: TPoint;
|
|
Button: TcxMouseButton; Shift: TShiftState; AViewInfo: TcxCustomEditViewInfo;
|
|
AIsMouseEvent: Boolean); override;
|
|
procedure CalculateButtonsViewInfo(ACanvas: TcxCanvas; const ABounds: TRect;
|
|
const P: TPoint; Button: TcxMouseButton; Shift: TShiftState;
|
|
AViewInfo: TcxCustomEditViewInfo; AIsMouseEvent: Boolean); override;
|
|
function GetEditConstantPartSize(ACanvas: TcxCanvas;
|
|
const AEditSizeProperties: TcxEditSizeProperties;
|
|
var MinContentSize: TSize; AViewInfo: TcxCustomEditViewInfo = nil): TSize; override;
|
|
class function IsButtonNativeStyle(ALookAndFeel: TcxLookAndFeel): Boolean; virtual;
|
|
property Properties: TcxCustomButtonGroupProperties read GetProperties;
|
|
end;
|
|
|
|
TcxButtonGroupViewDataClass = class of TcxButtonGroupViewData;
|
|
|
|
{ TcxCustomGroupBoxProperties }
|
|
|
|
TcxCustomGroupBoxProperties = class(TcxCustomEditProperties)
|
|
protected
|
|
class function GetViewDataClass: TcxCustomEditViewDataClass; override;
|
|
public
|
|
class function GetContainerClass: TcxContainerClass; override;
|
|
class function GetViewInfoClass: TcxContainerViewInfoClass; override;
|
|
end;
|
|
|
|
{ TcxButtonGroupItem }
|
|
|
|
TcxButtonGroupItem = class(TCollectionItem)
|
|
private
|
|
FCaption: TCaption;
|
|
FEnabled: Boolean;
|
|
FTag: TcxTag;
|
|
function GetIsCollectionDestroying: Boolean;
|
|
function IsTagStored: Boolean;
|
|
procedure SetCaption(const Value: TCaption);
|
|
procedure SetEnabled(Value: Boolean);
|
|
protected
|
|
procedure DoChanged(ACollection: TCollection; ACollectionOperation: TcxCollectionOperation;
|
|
AIndex: Integer = -1);
|
|
property Caption: TCaption read FCaption write SetCaption;
|
|
property Enabled: Boolean read FEnabled write SetEnabled default True;
|
|
property IsCollectionDestroying: Boolean read GetIsCollectionDestroying;
|
|
property Tag: TcxTag read FTag write FTag stored IsTagStored;
|
|
public
|
|
constructor Create(Collection: TCollection); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
function GetCaption: TCaption;
|
|
end;
|
|
|
|
{ TcxButtonGroupItems }
|
|
|
|
TcxButtonGroupItems = class(TOwnedCollection,
|
|
IUnknown, IcxCheckItems)
|
|
private
|
|
FChangedItemIndex: Integer;
|
|
FChangedItemOperation: TcxCollectionOperation;
|
|
FIsDestroying: Boolean;
|
|
FItemChanged: Boolean;
|
|
function GetItem(Index: Integer): TcxButtonGroupItem;
|
|
procedure SetItem(Index: Integer; Value: TcxButtonGroupItem);
|
|
|
|
{ IUnknown }
|
|
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
|
|
function _AddRef: Integer; stdcall;
|
|
function _Release: Integer; stdcall;
|
|
|
|
{ IcxCheckItems }
|
|
function IcxCheckItems.GetCaption = CheckItemsGetCaption;
|
|
function IcxCheckItems.GetCount = CheckItemsGetCount;
|
|
function CheckItemsGetCaption(Index: Integer): string;
|
|
function CheckItemsGetCount: Integer;
|
|
protected
|
|
procedure Update(Item: TCollectionItem); override;
|
|
property ChangedItemIndex: Integer read FChangedItemIndex;
|
|
property ChangedItemOperation: TcxCollectionOperation
|
|
read FChangedItemOperation;
|
|
property IsDestroying: Boolean read FIsDestroying;
|
|
property ItemChanged: Boolean read FItemChanged;
|
|
public
|
|
destructor Destroy; override;
|
|
procedure InternalNotify(AItem: TcxButtonGroupItem; AItemIndex: Integer;
|
|
AItemOperation: TcxCollectionOperation);
|
|
property Items[Index: Integer]: TcxButtonGroupItem
|
|
read GetItem write SetItem; default;
|
|
end;
|
|
|
|
TcxButtonGroupItemsClass = class of TcxButtonGroupItems;
|
|
|
|
{ TcxCustomButtonGroupProperties }
|
|
|
|
TcxCustomButtonGroupProperties = class(TcxCustomGroupBoxProperties)
|
|
private
|
|
FColumns: Integer;
|
|
FItems: TcxButtonGroupItems;
|
|
FWordWrap: Boolean;
|
|
procedure SetColumns(Value: Integer);
|
|
procedure SetItems(Value: TcxButtonGroupItems);
|
|
procedure SetWordWrap(Value: Boolean);
|
|
protected
|
|
class function GetViewDataClass: TcxCustomEditViewDataClass; override;
|
|
function CreateItems: TcxButtonGroupItems; virtual;
|
|
function GetButtonsPerColumn: Integer;
|
|
function GetColumnCount: Integer; virtual;
|
|
public
|
|
constructor Create(AOwner: TPersistent); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
function CreatePreviewProperties: TcxCustomEditProperties; override;
|
|
class function GetContainerClass: TcxContainerClass; override;
|
|
function GetSpecialFeatures: TcxEditSpecialFeatures; override;
|
|
function GetSupportedOperations: TcxEditSupportedOperations; override;
|
|
class function GetViewInfoClass: TcxContainerViewInfoClass; override;
|
|
// !!!
|
|
property Columns: Integer read FColumns write SetColumns default 1;
|
|
property Items: TcxButtonGroupItems read FItems write SetItems;
|
|
property WordWrap: Boolean read FWordWrap write SetWordWrap default False;
|
|
end;
|
|
|
|
{ TcxCustomGroupBox }
|
|
|
|
TcxCustomGroupBox = class(TcxCustomEdit)
|
|
private
|
|
FAlignment: TcxCaptionAlignment;
|
|
FCaptionBkColor: TColor; // deprecated
|
|
FCaptionFont: TFont;
|
|
FIsAccelCharHandling: Boolean;
|
|
FVisibleCaption: string;
|
|
procedure CalculateVisibleCaption;
|
|
function GetColor: TColor; // deprecated
|
|
function GetFont: TFont; // deprecated
|
|
procedure SetAlignment(Value: TcxCaptionAlignment);
|
|
procedure SetColor(Value: TColor); // deprecated
|
|
procedure SetFont(Value: TFont); // deprecated
|
|
{$IFNDEF DELPHI7}
|
|
procedure WMPrintClient(var Message: TMessage); message WM_PRINTCLIENT;
|
|
{$ENDIF}
|
|
procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
|
|
protected
|
|
procedure AdjustClientRect(var Rect: TRect); override;
|
|
function CanAutoSize: Boolean; override;
|
|
function CanFocusOnClick: Boolean; override;
|
|
procedure ContainerStyleChanged(Sender: TObject); override;
|
|
function DefaultParentColor: Boolean; override;
|
|
procedure FontChanged; override;
|
|
function GetShadowBounds: TRect; override;
|
|
procedure Initialize; override;
|
|
function InternalGetActiveStyle: TcxContainerStyle; override;
|
|
function InternalGetNotPublishedStyleValues: TcxEditStyleValues; override;
|
|
function IsContainerClass: Boolean; override;
|
|
function IsNativeBackground: Boolean; override;
|
|
procedure LookAndFeelChanged(Sender: TcxLookAndFeel;
|
|
AChangedValues: TcxLookAndFeelValues); override;
|
|
procedure TextChanged; override;
|
|
procedure AdjustCanvasFontSettings(ACanvas: TcxCanvas);
|
|
procedure CalculateCaptionFont;
|
|
function GetCaptionDrawingFlags: Integer;
|
|
function IsVerticalText: Boolean;
|
|
property CaptionBkColor: TColor read FCaptionBkColor write FCaptionBkColor
|
|
stored False; // deprecated
|
|
property Color: TColor read GetColor write SetColor stored False; // deprecated
|
|
property Ctl3D;
|
|
property Font: TFont read GetFont write SetFont stored False; // deprecated
|
|
property ParentBackground;
|
|
property TabStop default False;
|
|
public
|
|
{$IFDEF CBUILDER10}
|
|
constructor Create(AOwner: TComponent); override;
|
|
{$ENDIF}
|
|
destructor Destroy; override;
|
|
class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
|
|
property Alignment: TcxCaptionAlignment read FAlignment write SetAlignment
|
|
default alTopLeft;
|
|
property Transparent;
|
|
end;
|
|
|
|
{ TcxGroupBox }
|
|
|
|
TcxGroupBox = class(TcxCustomGroupBox)
|
|
published
|
|
property Align;
|
|
property Alignment;
|
|
property Anchors;
|
|
property BiDiMode;
|
|
property Caption;
|
|
property CaptionBkColor; // deprecated
|
|
property Color; // deprecated
|
|
property Constraints;
|
|
property Ctl3D;
|
|
property DockSite;
|
|
property DragCursor;
|
|
property DragKind;
|
|
property DragMode;
|
|
property Enabled;
|
|
property Font; // deprecated
|
|
property LookAndFeel; // deprecated
|
|
property ParentBackground;
|
|
property ParentBiDiMode;
|
|
property ParentColor;
|
|
property ParentCtl3D;
|
|
property ParentFont;
|
|
property ParentShowHint;
|
|
property PopupMenu;
|
|
property ShowHint;
|
|
property Style;
|
|
property StyleDisabled;
|
|
property StyleFocused;
|
|
property StyleHot;
|
|
property TabOrder;
|
|
property TabStop;
|
|
property Transparent;
|
|
property Visible;
|
|
property OnClick;
|
|
property OnContextPopup;
|
|
property OnDblClick;
|
|
property OnDockDrop;
|
|
property OnDockOver;
|
|
property OnDragDrop;
|
|
property OnDragOver;
|
|
property OnEndDock;
|
|
property OnEndDrag;
|
|
property OnEnter;
|
|
property OnExit;
|
|
property OnGetSiteInfo;
|
|
property OnMouseDown;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
property OnStartDock;
|
|
property OnStartDrag;
|
|
property OnUnDock;
|
|
end;
|
|
|
|
{ TcxCustomButtonGroup }
|
|
|
|
TcxCustomButtonGroup = class(TcxCustomGroupBox)
|
|
private
|
|
FButtons: TList;
|
|
procedure DoButtonDragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
procedure DoButtonDragOver(Sender, Source: TObject; X, Y: Integer;
|
|
State: TDragState; var Accept: Boolean);
|
|
procedure DoButtonKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
procedure DoButtonKeyPress(Sender: TObject; var Key: Char);
|
|
procedure DoButtonKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
procedure DoButtonMouseDown(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
procedure DoButtonMouseMove(Sender: TObject; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
procedure DoButtonMouseUp(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
procedure DoButtonMouseWheel(Sender: TObject;
|
|
Shift: TShiftState; WheelDelta: Integer;
|
|
MousePos: TPoint; var Handled: Boolean);
|
|
function GetProperties: TcxCustomButtonGroupProperties;
|
|
function GetActiveProperties: TcxCustomButtonGroupProperties;
|
|
procedure SetProperties(Value: TcxCustomButtonGroupProperties);
|
|
procedure WMWindowPosChanged(var Message: TWMWindowPosChanged);
|
|
message WM_WINDOWPOSCHANGED;
|
|
protected
|
|
function CanAutoSize: Boolean; override;
|
|
procedure ContainerStyleChanged(Sender: TObject); override;
|
|
procedure CursorChanged; override;
|
|
procedure DoEditKeyDown(var Key: Word; Shift: TShiftState); override;
|
|
procedure EnabledChanged; override;
|
|
procedure Initialize; override;
|
|
function IsButtonDC(ADC: THandle): Boolean; override;
|
|
function IsContainerClass: Boolean; override;
|
|
procedure PropertiesChanged(Sender: TObject); override;
|
|
procedure ReadState(Reader: TReader); override;
|
|
function RefreshContainer(const P: TPoint; Button: TcxMouseButton; Shift: TShiftState;
|
|
AIsMouseEvent: Boolean): Boolean; override;
|
|
procedure CreateHandle; override;
|
|
procedure ArrangeButtons; virtual;
|
|
function GetButtonDC(AButtonIndex: Integer): THandle; virtual; abstract;
|
|
function GetButtonIndexAt(const P: TPoint): Integer;
|
|
function GetButtonInstance: TWinControl; virtual; abstract;
|
|
function GetFocusedButtonIndex: Integer;
|
|
procedure InitButtonInstance(AButton: TWinControl); virtual;
|
|
procedure SetButtonCount(Value: Integer); virtual;
|
|
procedure SynchronizeButtonsStyle; virtual;
|
|
procedure UpdateButtons; virtual;
|
|
property InternalButtons: TList read FButtons;
|
|
property TabStop default True;
|
|
public
|
|
destructor Destroy; override;
|
|
procedure ActivateByMouse(Shift: TShiftState; X, Y: Integer;
|
|
var AEditData: TcxCustomEditData); override;
|
|
function Focused: Boolean; override;
|
|
class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
|
|
procedure GetTabOrderList(List: TList); override;
|
|
function IsButtonNativeStyle: Boolean;
|
|
property AutoSize default False;
|
|
property ActiveProperties: TcxCustomButtonGroupProperties
|
|
read GetActiveProperties;
|
|
property Properties: TcxCustomButtonGroupProperties read GetProperties
|
|
write SetProperties;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
{$IFDEF DELPHI6}
|
|
Variants,
|
|
{$ENDIF}
|
|
dxThemeConsts, dxThemeManager, dxUxTheme, cxEditUtils, Math;
|
|
|
|
type
|
|
TControlAccess = class(TControl);
|
|
TWinControlAccess = class(TWinControl);
|
|
|
|
function cxGroupBoxAlignment2GroupBoxCaption(AAlignment: TcxCaptionAlignment): TcxGroupBoxCaptionPosition;
|
|
begin
|
|
if AAlignment in [alTopLeft, alTopCenter, alTopRight] then
|
|
Result := cxgpTop
|
|
else
|
|
if AAlignment in [alBottomLeft, alBottomCenter, alBottomRight] then
|
|
Result := cxgpBottom
|
|
else
|
|
if AAlignment in [alLeftTop, alLeftCenter, alLeftBottom] then
|
|
Result := cxgpLeft
|
|
else
|
|
if AAlignment in [alRightTop, alRightCenter, alRightBottom] then
|
|
Result := cxgpRight
|
|
else
|
|
Result := cxgpCenter;
|
|
end;
|
|
|
|
{ TcxGroupBoxButtonViewInfo }
|
|
|
|
function TcxGroupBoxButtonViewInfo.GetGlyphRect(ACanvas: TcxCanvas; AGlyphSize: TSize; AAlignment: TLeftRight; AIsPaintCopy: Boolean): TRect;
|
|
begin
|
|
Result.Top := Bounds.Top + (Bounds.Bottom - Bounds.Top - AGlyphSize.cy) div 2;
|
|
Result.Bottom := Result.Top + AGlyphSize.cy;
|
|
if AAlignment = taRightJustify then
|
|
begin
|
|
Result.Left := Bounds.Left;
|
|
Result.Right := Result.Left + AGlyphSize.cx;
|
|
end
|
|
else
|
|
begin
|
|
Result.Right := Bounds.Right;
|
|
Result.Left := Result.Right - AGlyphSize.cx;
|
|
end;
|
|
end;
|
|
|
|
{ TcxGroupBoxViewInfo }
|
|
|
|
constructor TcxGroupBoxViewInfo.Create;
|
|
begin
|
|
inherited Create;
|
|
CaptionBitmap := TBitmap.Create;
|
|
CaptionBitmap.PixelFormat := pf32bit;
|
|
CaptionBitmap.HandleType := bmDDB;
|
|
CaptionBitmapCanvas := TcxCanvas.Create(CaptionBitmap.Canvas);
|
|
end;
|
|
|
|
destructor TcxGroupBoxViewInfo.Destroy;
|
|
begin
|
|
FreeAndNil(CaptionBitmapCanvas);
|
|
FreeAndNil(CaptionBitmap);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TcxGroupBoxViewInfo.GetButtonViewInfoClass: TcxEditButtonViewInfoClass;
|
|
begin
|
|
Result := TcxGroupBoxButtonViewInfo;
|
|
end;
|
|
|
|
procedure TcxGroupBoxViewInfo.DrawCaption(ACanvas: TcxCanvas);
|
|
var
|
|
AFlags, X, Y: Integer;
|
|
begin
|
|
if (Edit = nil) or (Edit.FVisibleCaption = '') then Exit;
|
|
|
|
Edit.AdjustCanvasFontSettings(ACanvas);
|
|
if Painter <> nil then
|
|
ACanvas.Brush.Style := bsClear
|
|
else
|
|
if Edit.IsTransparentBackground then
|
|
begin
|
|
cxDrawTransparentControlBackground(Edit, ACanvas, ControlRect);
|
|
ACanvas.Brush.Style := bsClear;
|
|
end
|
|
else
|
|
ACanvas.Brush.Color := BackgroundColor;
|
|
|
|
if Edit.FVisibleCaption = '' then
|
|
Exit;
|
|
|
|
if not Edit.IsVerticalText then
|
|
cxDrawText(ACanvas.Handle, Edit.FVisibleCaption, TextRect, Edit.GetCaptionDrawingFlags)
|
|
else
|
|
begin
|
|
AFlags := ETO_CLIPPED;
|
|
if not Edit.IsTransparentBackground and (Painter = nil) then
|
|
AFlags := AFlags or ETO_OPAQUE;
|
|
if Edit.FAlignment in [alLeftTop, alLeftCenter, alLeftBottom] then
|
|
begin
|
|
X := TextRect.Left;
|
|
Y := TextRect.Bottom - 1;
|
|
end
|
|
else
|
|
begin
|
|
X := TextRect.Right;
|
|
Y := TextRect.Top + 1;
|
|
end;
|
|
cxExtTextOut(ACanvas.Handle, Edit.FVisibleCaption, Point(X, Y), TextRect, AFlags);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxGroupBoxViewInfo.InternalDrawCustom(ACanvas: TcxCanvas);
|
|
|
|
function GetThemeBackgroundRect(ACanvas: TcxCanvas): TRect;
|
|
begin
|
|
Result := ControlRect;
|
|
case Edit.FAlignment of
|
|
alTopLeft, alTopCenter, alTopRight:
|
|
Result.Top := ACanvas.TextHeight('Qq') div 2;
|
|
alBottomLeft, alBottomCenter, alBottomRight:
|
|
Dec(Result.Bottom, ACanvas.TextHeight('Qq') div 2);
|
|
alLeftTop, alLeftCenter, alLeftBottom:
|
|
Result.Left := ACanvas.TextHeight('Qq') div 2;
|
|
alRightTop, alRightCenter, alRightBottom:
|
|
Dec(Result.Right, ACanvas.TextHeight('Qq') div 2);
|
|
end;
|
|
end;
|
|
|
|
procedure InternalDrawNativeShape(ACanvas: TcxCanvas; const ACaptionRect: TRect);
|
|
var
|
|
ABackgroundRect, R: TRect;
|
|
AClipRgn: TcxRegion;
|
|
ANativeState: Integer;
|
|
ATheme: TdxTheme;
|
|
begin
|
|
AClipRgn := ACanvas.GetClipRegion;
|
|
try
|
|
ATheme := OpenTheme(totButton);
|
|
if Enabled then
|
|
ANativeState := GBS_NORMAL
|
|
else
|
|
ANativeState := GBS_DISABLED;
|
|
|
|
R := ControlRect;
|
|
if Edit.IsTransparent then
|
|
cxDrawTransparentControlBackground(Edit, ACanvas, R)
|
|
else
|
|
if Edit.IsNativeBackground and
|
|
IsThemeBackgroundPartiallyTransparent(ATheme, BP_GROUPBOX, ANativeState) then
|
|
begin
|
|
cxDrawThemeParentBackground(Edit, ACanvas, R);
|
|
end
|
|
else
|
|
cxEditFillRect(ACanvas.Handle, R, GetSolidBrush(ACanvas, BackgroundColor));
|
|
|
|
if BorderStyle <> ebsNone then
|
|
begin
|
|
if Edit.FAlignment <> alCenterCenter then
|
|
ACanvas.ExcludeClipRect(ACaptionRect);
|
|
ABackgroundRect := GetThemeBackgroundRect(ACanvas);
|
|
DrawThemeBackground(ATheme, ACanvas.Handle, BP_GROUPBOX, ANativeState,
|
|
ABackgroundRect);
|
|
end;
|
|
finally
|
|
ACanvas.SetClipRegion(AClipRgn, roSet);
|
|
end;
|
|
end;
|
|
|
|
procedure DrawFrame(ACanvas: TcxCanvas; R: TRect);
|
|
begin
|
|
case BorderStyle of
|
|
ebsSingle: ACanvas.FrameRect(R, BorderColor, 1, Edit.ActiveStyle.Edges, True);
|
|
ebsThick: ACanvas.FrameRect(R, BorderColor, 2, Edit.ActiveStyle.Edges, True);
|
|
ebsFlat:
|
|
begin
|
|
ACanvas.FrameRect(R, clBtnShadow, 1, Edit.ActiveStyle.Edges, True);
|
|
InflateRect(R, -1, -1);
|
|
ACanvas.FrameRect(R, clBtnHighlight, 1, Edit.ActiveStyle.Edges, True);
|
|
end;
|
|
ebs3D:
|
|
if Edit.Ctl3D then
|
|
begin
|
|
Dec(R.Right);
|
|
Dec(R.Bottom);
|
|
ACanvas.FrameRect(R, clBtnShadow, 1, Edit.ActiveStyle.Edges, True);
|
|
OffsetRect(R, 1, 1);
|
|
ACanvas.FrameRect(R, clBtnHighlight, 1, Edit.ActiveStyle.Edges, True);
|
|
end
|
|
else
|
|
begin
|
|
ACanvas.FrameRect(R, clWindowFrame, 1, Edit.ActiveStyle.Edges, True);
|
|
InflateRect(R, -1, -1);
|
|
ACanvas.FrameRect(R, BackgroundColor, 1, Edit.ActiveStyle.Edges, True);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure InternalDrawUsualShape(ACanvas: TcxCanvas);
|
|
var
|
|
AFrameRect: TRect;
|
|
ABorderWidth: Integer;
|
|
begin
|
|
ABorderWidth := GetContainerBorderWidth(TcxContainerBorderStyle(BorderStyle));
|
|
|
|
AFrameRect := BorderRect;
|
|
ExtendRectByBorders(AFrameRect, ABorderWidth, Edges);
|
|
DrawFrame(ACanvas, AFrameRect);
|
|
|
|
if Shadow then
|
|
DrawContainerShadow(ACanvas, AFrameRect);
|
|
if Edit.IsTransparent then
|
|
cxDrawTransparentControlBackground(Edit, ACanvas, ControlRect)
|
|
else
|
|
cxEditFillRect(ACanvas, ControlRect, BackgroundColor)
|
|
end;
|
|
|
|
procedure DrawShape;
|
|
begin
|
|
if NativeStyle then
|
|
InternalDrawNativeShape(ACanvas, CaptionRect)
|
|
else
|
|
InternalDrawUsualShape(ACanvas);
|
|
end;
|
|
|
|
var
|
|
AClipRgn: TcxRegion;
|
|
begin
|
|
if RectVisible(ACanvas.Handle, CaptionRect) then
|
|
begin
|
|
AClipRgn := ACanvas.GetClipRegion;
|
|
try
|
|
ACanvas.ExcludeClipRect(CaptionRect);
|
|
SetWindowOrgEx(CaptionBitmap.Canvas.Handle, CaptionRect.Left,
|
|
CaptionRect.Top, nil);
|
|
CaptionBitmapCanvas.Canvas.Lock;
|
|
try
|
|
DrawShape;
|
|
DrawCaption(CaptionBitmapCanvas);
|
|
SetWindowOrgEx(CaptionBitmap.Canvas.Handle, 0, 0, nil);
|
|
finally
|
|
CaptionBitmapCanvas.Canvas.Unlock;
|
|
end;
|
|
finally
|
|
ACanvas.SetClipRegion(AClipRgn, roSet);
|
|
end;
|
|
ACanvas.CopyRect(CaptionRect, CaptionBitmap.Canvas,
|
|
Rect(0, 0, CaptionBitmap.Width, CaptionBitmap.Height));
|
|
end
|
|
else
|
|
DrawShape;
|
|
end;
|
|
|
|
procedure TcxGroupBoxViewInfo.InternalDrawByPainter(ACanvas: TcxCanvas;
|
|
APainter: TcxCustomLookAndFeelPainterClass);
|
|
var
|
|
ACaptionPos: TcxGroupBoxCaptionPosition;
|
|
begin
|
|
if Assigned(Edit) and Assigned(APainter) then
|
|
begin
|
|
ACaptionPos := cxGroupBoxAlignment2GroupBoxCaption(Edit.Alignment);
|
|
|
|
if Painter.IsGroupBoxTransparent(True, ACaptionPos) or
|
|
Painter.IsGroupBoxTransparent(False, ACaptionPos)
|
|
then
|
|
cxDrawTransparentControlBackground(Edit, ACanvas, ControlRect);
|
|
|
|
Painter.DrawGroupBoxContent(ACanvas, BorderRect, ACaptionPos);
|
|
Painter.DrawGroupBoxCaption(ACanvas, CaptionRect, ACaptionPos);
|
|
DrawCaption(ACanvas);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxGroupBoxViewInfo.InternalPaint(ACanvas: TcxCanvas);
|
|
begin
|
|
if IsInplace then
|
|
begin
|
|
if Edit = nil then
|
|
inherited InternalPaint(ACanvas)
|
|
else
|
|
if IsCustomBackground then
|
|
DrawBackground(ACanvas)
|
|
else
|
|
cxEditFillRect(ACanvas, Bounds, BackgroundColor);
|
|
Exit;
|
|
end;
|
|
|
|
if Painter = nil then
|
|
InternalDrawCustom(ACanvas)
|
|
else
|
|
InternalDrawByPainter(ACanvas, Painter);
|
|
|
|
if Edit.IsDBEditPaintCopyDrawing then
|
|
DrawButtons(ACanvas);
|
|
end;
|
|
|
|
function TcxGroupBoxViewInfo.GetControlRect: TRect;
|
|
begin
|
|
Result := cxContainer.GetControlRect(Edit);
|
|
end;
|
|
|
|
function TcxGroupBoxViewInfo.GetEdit: TcxCustomGroupBox;
|
|
begin
|
|
Result := TcxCustomGroupBox(FEdit);
|
|
end;
|
|
|
|
{ TcxGroupBoxViewData }
|
|
|
|
procedure TcxGroupBoxViewData.Calculate(ACanvas: TcxCanvas;
|
|
const ABounds: TRect; const P: TPoint; Button: TcxMouseButton; Shift: TShiftState;
|
|
AViewInfo: TcxCustomEditViewInfo; AIsMouseEvent: Boolean);
|
|
var
|
|
AEditViewInfo: TcxGroupBoxViewInfo;
|
|
begin
|
|
AEditViewInfo := TcxGroupBoxViewInfo(AViewInfo);
|
|
AEditViewInfo.IsDesigning := IsDesigning;
|
|
inherited Calculate(ACanvas, ABounds, P, Button, Shift, AViewInfo, AIsMouseEvent);
|
|
if not IsInplace then
|
|
begin
|
|
Edit.CalculateCaptionFont;
|
|
Edit.CalculateVisibleCaption;
|
|
if Style.LookAndFeel.SkinPainter <> nil then
|
|
CalcRects(ACanvas, AEditViewInfo)
|
|
else
|
|
begin
|
|
AEditViewInfo.CaptionRect := GetCaptionRect(ACanvas);
|
|
AEditViewInfo.TextRect := GetCaptionRect(ACanvas);
|
|
end;
|
|
|
|
with AEditViewInfo.CaptionRect do
|
|
begin
|
|
AEditViewInfo.CaptionBitmap.Width := Max(0, Right - Left);
|
|
AEditViewInfo.CaptionBitmap.Height := Max(0, Bottom - Top);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxGroupBoxViewData.GetBorderColor: TColor;
|
|
begin
|
|
if Style.BorderStyle in [ebsUltraFlat, ebsOffice11] then
|
|
begin
|
|
if Enabled then
|
|
Result := GetEditBorderHighlightColor(Style.BorderStyle = ebsOffice11)
|
|
else
|
|
Result := clBtnShadow;
|
|
end
|
|
else
|
|
Result := Style.BorderColor;
|
|
end;
|
|
|
|
function TcxGroupBoxViewData.GetBorderExtent: TRect;
|
|
var
|
|
AHeaderSideBorderOffset: Integer;
|
|
begin
|
|
Result := inherited GetBorderExtent;
|
|
if not IsInplace and (Edit.FAlignment <> alCenterCenter) then
|
|
begin
|
|
cxScreenCanvas.Font := Edit.FCaptionFont;
|
|
AHeaderSideBorderOffset := cxScreenCanvas.TextHeight('Qq') div 2 - 1 +
|
|
cxEditMaxBorderWidth;
|
|
case Edit.FAlignment of
|
|
alTopLeft, alTopCenter, alTopRight:
|
|
Result.Top := AHeaderSideBorderOffset;
|
|
alBottomLeft, alBottomCenter, alBottomRight:
|
|
Result.Bottom := AHeaderSideBorderOffset;
|
|
alLeftTop, alLeftCenter, alLeftBottom:
|
|
Result.Left := AHeaderSideBorderOffset - 1;
|
|
alRightTop, alRightCenter, alRightBottom:
|
|
Result.Right := AHeaderSideBorderOffset - 1;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxGroupBoxViewData.GetClientExtent(ACanvas: TcxCanvas;
|
|
AViewInfo: TcxCustomEditViewInfo): TRect;
|
|
var
|
|
AHeaderSideClientExtent: Integer;
|
|
ABorderRect: TRect;
|
|
begin
|
|
if not IsInplace and (Style.LookAndFeel.SkinPainter <> nil) then
|
|
begin
|
|
ABorderRect := Style.LookAndFeel.SkinPainter.GroupBoxBorderSize(False,
|
|
cxGroupBoxAlignment2GroupBoxCaption(Edit.Alignment));
|
|
with ABorderRect do
|
|
Result := Rect(Left + cxEditMaxBorderWidth, Top + cxEditMaxBorderWidth,
|
|
Right + cxEditMaxBorderWidth, Bottom + cxEditMaxBorderWidth);
|
|
if Edit.HasShadow then
|
|
begin
|
|
Result.Right := Result.Right + cxEditShadowWidth;
|
|
Result.Bottom := Result.Bottom + cxEditShadowWidth;
|
|
end;
|
|
if Edit.FAlignment <> alCenterCenter then
|
|
begin
|
|
cxScreenCanvas.Font := Edit.FCaptionFont;
|
|
AHeaderSideClientExtent := cxScreenCanvas.TextHeight('Qq') +
|
|
Result.Top + cxEditMaxBorderWidth + 1;
|
|
case Edit.FAlignment of
|
|
alTopLeft, alTopCenter, alTopRight:
|
|
Result.Top := AHeaderSideClientExtent;
|
|
alBottomLeft, alBottomCenter, alBottomRight:
|
|
Result.Bottom := AHeaderSideClientExtent;
|
|
alLeftTop, alLeftCenter, alLeftBottom:
|
|
Result.Left := AHeaderSideClientExtent;
|
|
alRightTop, alRightCenter, alRightBottom:
|
|
Result.Right := AHeaderSideClientExtent;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
Result := inherited GetBorderExtent;
|
|
if not IsInplace and (Edit.FAlignment <> alCenterCenter) then
|
|
begin
|
|
cxScreenCanvas.Font := Edit.FCaptionFont;
|
|
AHeaderSideClientExtent := cxScreenCanvas.TextHeight('Qq') +
|
|
cxEditMaxBorderWidth + 1;
|
|
case Edit.FAlignment of
|
|
alTopLeft, alTopCenter, alTopRight:
|
|
Result.Top := AHeaderSideClientExtent;
|
|
alBottomLeft, alBottomCenter, alBottomRight:
|
|
Result.Bottom := AHeaderSideClientExtent;
|
|
alLeftTop, alLeftCenter, alLeftBottom:
|
|
Result.Left := AHeaderSideClientExtent;
|
|
alRightTop, alRightCenter, alRightBottom:
|
|
Result.Right := AHeaderSideClientExtent;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxGroupBoxViewData.HasShadow: Boolean;
|
|
begin
|
|
Result := (Edit.FAlignment in [alTopLeft, alTopCenter,
|
|
alTopRight, alLeftTop, alLeftCenter, alLeftBottom, alCenterCenter]) and
|
|
inherited HasShadow;
|
|
end;
|
|
|
|
class function TcxGroupBoxViewData.IsNativeStyle(ALookAndFeel: TcxLookAndFeel): Boolean;
|
|
begin
|
|
Result := AreVisualStylesMustBeUsed(
|
|
ALookAndFeel.NativeStyle or (ALookAndFeel.Kind = lfOffice11), totEdit) and
|
|
(ALookAndFeel.SkinPainter = nil);
|
|
end;
|
|
|
|
function TcxGroupBoxViewData.GetContainerState(const ABounds: TRect;
|
|
const P: TPoint; Button: TcxMouseButton; Shift: TShiftState;
|
|
AIsMouseEvent: Boolean): TcxContainerState;
|
|
begin
|
|
if Enabled then
|
|
Result := [csNormal]
|
|
else
|
|
Result := [csDisabled];
|
|
end;
|
|
|
|
function TcxGroupBoxViewData.GetCaptionRect(ACanvas: TcxCanvas): TRect;
|
|
const
|
|
CaptionRectLeftBound = 8;
|
|
var
|
|
AFlags, AShadowWidth, ATextHeight, ATextWidth: Integer;
|
|
begin
|
|
if Edit.FVisibleCaption = '' then
|
|
begin
|
|
Result := cxEmptyRect;
|
|
Exit;
|
|
end;
|
|
|
|
Edit.AdjustCanvasFontSettings(ACanvas);
|
|
with ACanvas do
|
|
begin
|
|
ATextHeight := TextHeight('Qq');
|
|
Result := Rect(CaptionRectLeftBound, 0, 0, ATextHeight);
|
|
AFlags := Edit.GetCaptionDrawingFlags;
|
|
cxDrawText(Handle, Edit.FVisibleCaption, Result, AFlags or DT_CALCRECT);
|
|
ATextWidth := Result.Right - Result.Left;
|
|
|
|
if Style.Shadow then
|
|
AShadowWidth := cxContainerShadowWidth
|
|
else
|
|
AShadowWidth := 0;
|
|
|
|
if not Edit.IsVerticalText then
|
|
begin
|
|
case Edit.FAlignment of
|
|
alTopCenter, alBottomCenter, alCenterCenter:
|
|
OffsetRect(Result, -Result.Left + (Edit.Width - AShadowWidth - (Result.Right - Result.Left)) div 2, 0);
|
|
alTopRight, alBottomRight:
|
|
OffsetRect(Result, Edit.Width - Result.Right - Result.Left - AShadowWidth, 0);
|
|
end;
|
|
case Edit.FAlignment of
|
|
alBottomLeft, alBottomCenter, alBottomRight:
|
|
begin
|
|
Result := Rect(Result.Left, Edit.Height - Result.Top -
|
|
(Result.Bottom - Result.Top), Result.Right, Edit.Height - Result.Top);
|
|
OffsetRect(Result, 0, -2);
|
|
end;
|
|
alCenterCenter:
|
|
OffsetRect(Result, 0, -Result.Top + (Edit.Height - AShadowWidth -
|
|
(Result.Bottom - Result.Top)) div 2);
|
|
end;
|
|
end
|
|
else
|
|
case Edit.FAlignment of
|
|
alLeftTop:
|
|
begin
|
|
Result := Rect(Result.Top - 1, Result.Left, Result.Bottom - 1, 0);
|
|
Result.Bottom := Result.Top + ATextWidth;
|
|
end;
|
|
alLeftCenter:
|
|
begin
|
|
Result := Rect(Result.Top - 1, 0, Result.Bottom - 1,
|
|
Edit.Height - AShadowWidth - (Edit.Height - AShadowWidth - ATextWidth) div 2);
|
|
Result.Top := Result.Bottom - ATextWidth;
|
|
end;
|
|
alLeftBottom:
|
|
begin
|
|
Result := Rect(Result.Top - 1, 0, Result.Bottom - 1,
|
|
Edit.Height - AShadowWidth - Result.Left);
|
|
Result.Top := Result.Bottom - ATextWidth;
|
|
end;
|
|
alRightTop:
|
|
Result := Rect(Edit.Width - Result.Bottom + 1, Result.Left,
|
|
Edit.Width - Result.Top + 1, Result.Left + ATextWidth);
|
|
alRightCenter:
|
|
begin
|
|
Result := Rect(Edit.Width - Result.Bottom + 1,
|
|
(Edit.Height - ATextWidth) div 2, Edit.Width - Result.Top + 1, 0);
|
|
Result.Bottom := Result.Top + ATextWidth;
|
|
end;
|
|
alRightBottom:
|
|
Result := Rect(Edit.Width - Result.Bottom + 1,
|
|
Edit.Height - Result.Left - ATextWidth, Edit.Width - Result.Top + 1,
|
|
Edit.Height - Result.Left);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxGroupBoxViewData.GetEdit: TcxCustomGroupBox;
|
|
begin
|
|
Result := TcxCustomGroupBox(FEdit);
|
|
end;
|
|
|
|
procedure TcxGroupBoxViewData.CalcRects(ACanvas: TcxCanvas;
|
|
AEditViewInfo: TcxGroupBoxViewInfo);
|
|
var
|
|
ABorderSize: TRect;
|
|
ACaptionPos: TcxGroupBoxCaptionPosition;
|
|
ATextHeight: Integer;
|
|
ATextWidth: Integer;
|
|
begin
|
|
with AEditViewInfo do
|
|
begin
|
|
Edit.AdjustCanvasFontSettings(ACanvas);
|
|
ATextHeight := Max(ACanvas.TextHeight(Edit.FVisibleCaption),
|
|
ACanvas.TextHeight('Qq'));
|
|
ATextWidth := ACanvas.TextWidth(Edit.FVisibleCaption);
|
|
|
|
BorderRect := ControlRect;
|
|
ACaptionPos := cxGroupBoxAlignment2GroupBoxCaption(Edit.Alignment);
|
|
ABorderSize := Style.LookAndFeel.SkinPainter.GroupBoxBorderSize(True, ACaptionPos);
|
|
case ACaptionPos of
|
|
cxgpTop:
|
|
begin
|
|
CaptionRect := Rect(BorderRect.Left, ControlRect.Top, BorderRect.Right,
|
|
ControlRect.Top + ATextHeight + ABorderSize.Top + ABorderSize.Bottom);
|
|
BorderRect.Top := CaptionRect.Bottom;
|
|
end;
|
|
cxgpBottom:
|
|
begin
|
|
CaptionRect := Rect(BorderRect.Left,
|
|
ControlRect.Bottom - ABorderSize.Top - ABorderSize.Bottom - ATextHeight,
|
|
BorderRect.Right, ControlRect.Bottom);
|
|
BorderRect.Bottom := CaptionRect.Top;
|
|
end;
|
|
cxgpLeft:
|
|
begin
|
|
CaptionRect := Rect(ControlRect.Left, BorderRect.Top,
|
|
ControlRect.Left + ATextHeight + ABorderSize.Left + ABorderSize.Right,
|
|
BorderRect.Bottom);
|
|
BorderRect.Left := CaptionRect.Right;
|
|
end;
|
|
cxgpRight:
|
|
begin
|
|
CaptionRect := Rect(ControlRect.Right - ATextHeight - ABorderSize.Right,
|
|
BorderRect.Top, ControlRect.Right, BorderRect.Bottom);
|
|
BorderRect.Right := CaptionRect.Left;
|
|
end;
|
|
cxgpCenter:
|
|
begin
|
|
CaptionRect.Left := (ControlRect.Right + ControlRect.Left - ATextWidth) div 2;
|
|
CaptionRect.Top := (ControlRect.Bottom + ControlRect.Top - ATextHeight) div 2;
|
|
CaptionRect.Bottom := CaptionRect.Top + ATextHeight;
|
|
CaptionRect.Right := CaptionRect.Left + ATextWidth;
|
|
BorderRect := ControlRect;
|
|
end;
|
|
end;
|
|
with ABorderSize do
|
|
TextRect := Rect(CaptionRect.Left + Left, CaptionRect.Top + Top,
|
|
CaptionRect.Right - Right, CaptionRect.Bottom - Bottom);
|
|
if Edit.Alignment in [alTopRight, alBottomRight] then
|
|
TextRect.Left := TextRect.Right - ATextWidth
|
|
else
|
|
if Edit.Alignment in [alTopCenter, alBottomCenter] then
|
|
TextRect.Left := (TextRect.Left + TextRect.Right - ATextWidth) div 2
|
|
else
|
|
if Edit.Alignment in [alLeftTop, alRightTop] then
|
|
TextRect.Bottom := TextRect.Top + ATextWidth
|
|
else
|
|
if Edit.Alignment in [alLeftCenter, alRightCenter] then
|
|
begin
|
|
TextRect.Top := (TextRect.Bottom + TextRect.Top - ATextWidth) div 2;
|
|
TextRect.Bottom := TextRect.Top + ATextWidth;
|
|
end
|
|
else
|
|
if Edit.Alignment in [alLeftBottom, alRightBottom] then
|
|
TextRect.Top := TextRect.Bottom - ATextWidth
|
|
else
|
|
end;
|
|
end;
|
|
|
|
{ TcxButtonGroupViewInfo }
|
|
|
|
procedure TcxButtonGroupViewInfo.DrawEditButton(ACanvas: TcxCanvas;
|
|
AButtonVisibleIndex: Integer);
|
|
var
|
|
AButtonViewInfo: TcxGroupBoxButtonViewInfo;
|
|
AGlyphRect: TRect;
|
|
begin
|
|
AButtonViewInfo := TcxGroupBoxButtonViewInfo(ButtonsInfo[AButtonVisibleIndex]);
|
|
AGlyphRect := AButtonViewInfo.GetGlyphRect(ACanvas, GetGlyphSize,
|
|
Alignment, IsDBEditPaintCopyDrawing);
|
|
if not IsDBEditPaintCopyDrawing then
|
|
DrawEditBackground(ACanvas, AButtonViewInfo.Bounds, AGlyphRect,
|
|
IsButtonGlypthTransparent(AButtonViewInfo));
|
|
DrawButtonGlyph(ACanvas, AButtonViewInfo, AGlyphRect);
|
|
DrawButtonCaption(ACanvas, AButtonViewInfo, AGlyphRect);
|
|
end;
|
|
|
|
function TcxButtonGroupViewInfo.GetGlyphSize: TSize;
|
|
begin
|
|
Result := GlyphSize;
|
|
end;
|
|
|
|
{ TcxButtonGroupViewData }
|
|
|
|
procedure TcxButtonGroupViewData.Calculate(ACanvas: TcxCanvas;
|
|
const ABounds: TRect; const P: TPoint; Button: TcxMouseButton;
|
|
Shift: TShiftState; AViewInfo: TcxCustomEditViewInfo;
|
|
AIsMouseEvent: Boolean);
|
|
begin
|
|
inherited Calculate(ACanvas, ABounds, P, Button, Shift, AViewInfo,
|
|
AIsMouseEvent);
|
|
with TcxButtonGroupViewInfo(AViewInfo) do
|
|
begin
|
|
DrawTextFlags := GetDrawTextFlags;
|
|
CaptionExtent := GetCaptionRectExtent;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxButtonGroupViewData.CalculateButtonsViewInfo(ACanvas: TcxCanvas;
|
|
const ABounds: TRect; const P: TPoint; Button: TcxMouseButton;
|
|
Shift: TShiftState; AViewInfo: TcxCustomEditViewInfo; AIsMouseEvent: Boolean);
|
|
|
|
procedure CalculateButtonStates;
|
|
var
|
|
AButtonsCount, APrevPressedButton, I: Integer;
|
|
AButtonViewInfo: TcxGroupBoxButtonViewInfo;
|
|
ACapturePressing, AHoldPressing, AIsButtonPressed, AMouseButtonPressing: Boolean;
|
|
begin
|
|
AButtonsCount := Properties.Items.Count;
|
|
AViewInfo.IsButtonReallyPressed := False;
|
|
if AIsMouseEvent then
|
|
APrevPressedButton := AViewInfo.PressedButton
|
|
else
|
|
APrevPressedButton := -1;
|
|
AViewInfo.PressedButton := -1;
|
|
AViewInfo.SelectedButton := -1;
|
|
|
|
for I := 0 to AButtonsCount - 1 do
|
|
begin
|
|
AButtonViewInfo := TcxGroupBoxButtonViewInfo(AViewInfo.ButtonsInfo[I]);
|
|
AButtonViewInfo.Index := I;
|
|
AButtonViewInfo.Data.NativeStyle := IsButtonNativeStyle(Style.LookAndFeel);
|
|
AButtonViewInfo.Data.Transparent := (Self.Style.ButtonTransparency = ebtAlways) or
|
|
(Self.Style.ButtonTransparency = ebtInactive) and not Selected;
|
|
|
|
AButtonViewInfo.Data.BackgroundColor := AViewInfo.BackgroundColor;
|
|
AIsButtonPressed := IsButtonPressed(AViewInfo, I);
|
|
with AButtonViewInfo do
|
|
begin
|
|
if not Enabled then
|
|
Data.State := ebsDisabled
|
|
else
|
|
if AIsButtonPressed or (not IsDesigning and PtInRect(AButtonViewInfo.Bounds, P)) then
|
|
begin
|
|
ACapturePressing := (Button = cxmbNone) and (ButtonToShift(mbLeft) *
|
|
Shift <> []) and (Data.State = ebsNormal) and (GetCaptureButtonVisibleIndex =
|
|
I);
|
|
AMouseButtonPressing := (Button = ButtonTocxButton(mbLeft)) and
|
|
((Shift = ButtonToShift(mbLeft)) or
|
|
(Shift = ButtonToShift(mbLeft) + [ssDouble]));
|
|
AHoldPressing := (Data.State = ebsPressed) and (Shift * ButtonToShift(mbLeft) <> []);
|
|
if AIsButtonPressed or AMouseButtonPressing or AHoldPressing or
|
|
ACapturePressing then
|
|
AViewInfo.IsButtonReallyPressed := True;
|
|
if not AIsButtonPressed and (Shift = []) and not ACapturePressing then
|
|
begin
|
|
Data.State := ebsSelected;
|
|
AViewInfo.SelectedButton := I;
|
|
end
|
|
else
|
|
if (AIsButtonPressed or ACapturePressing and CanPressButton(AViewInfo, I) or ((Shift = [ssLeft]) or (Shift = [ssLeft, ssDouble])) and
|
|
((Button = cxmbLeft) and CanPressButton(AViewInfo, I) or
|
|
(APrevPressedButton = I))) or AHoldPressing then
|
|
begin
|
|
Data.State := ebsPressed;
|
|
AViewInfo.PressedButton := I;
|
|
end
|
|
else
|
|
Data.State := ebsNormal;
|
|
end
|
|
else
|
|
Data.State := ebsNormal;
|
|
|
|
CalculateButtonNativeState(AViewInfo, AButtonViewInfo);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
AButtonsCount: Integer;
|
|
begin
|
|
AButtonsCount := Properties.Items.Count;
|
|
TcxGroupBoxViewInfo(AViewInfo).SetButtonCount(AButtonsCount);
|
|
if AButtonsCount = 0 then
|
|
Exit;
|
|
|
|
CalculateButtonViewInfos(AViewInfo);
|
|
CalculateButtonPositions(ACanvas, AViewInfo);
|
|
CalculateButtonStates;
|
|
end;
|
|
|
|
function TcxButtonGroupViewData.GetEditConstantPartSize(ACanvas: TcxCanvas;
|
|
const AEditSizeProperties: TcxEditSizeProperties;
|
|
var MinContentSize: TSize; AViewInfo: TcxCustomEditViewInfo = nil): TSize;
|
|
var
|
|
AButtonsCount, AButtonsPerColumn, AColumnsCount: Integer;
|
|
ACaption: string;
|
|
AColumnWidth, AMaxButtonHeight: Integer;
|
|
ADefaultButtonHeight, AButtonHeight: Integer;
|
|
AFlags: Integer;
|
|
AMaxColumnWidth: Integer;
|
|
ASizeCorrection: TSize;
|
|
ATextWidth: Integer;
|
|
I: Integer;
|
|
R: TRect;
|
|
AEditMetrics: TcxEditMetrics;
|
|
begin
|
|
MinContentSize := Size(0, 0);
|
|
ACanvas.Font := Style.GetVisibleFont;
|
|
ASizeCorrection := Self.GetEditContentSizeCorrection;
|
|
AButtonsCount := Properties.Items.Count;
|
|
AColumnsCount := Properties.GetColumnCount;
|
|
GetEditMetrics(AEditSizeProperties.Width >= 0, ACanvas, AEditMetrics);
|
|
ADefaultButtonHeight := ACanvas.TextHeight('Zg') + ASizeCorrection.cy;
|
|
if AEditSizeProperties.Width >= 0 then
|
|
begin
|
|
Result.cx := AEditSizeProperties.Width;
|
|
if AButtonsCount = 0 then
|
|
Result.cy := ADefaultButtonHeight
|
|
else
|
|
begin
|
|
Result.cy := 0;
|
|
AButtonsPerColumn := Properties.GetButtonsPerColumn;
|
|
AColumnWidth := AEditSizeProperties.Width - ContentOffset.Left -
|
|
ContentOffset.Right + AEditMetrics.AutoHeightWidthCorrection -
|
|
AEditMetrics.ColumnOffset * (AColumnsCount - 1);
|
|
AColumnWidth := AColumnWidth div AColumnsCount - AEditMetrics.ButtonSize.cx -
|
|
AEditMetrics.AutoHeightColumnWidthCorrection;
|
|
if AColumnWidth <= 0 then
|
|
AColumnWidth := 1;
|
|
AMaxButtonHeight := ADefaultButtonHeight;
|
|
Include(PaintOptions, epoAutoHeight);
|
|
AFlags := GetDrawTextFlags and not cxAlignVCenter or cxAlignTop;
|
|
for I := 0 to AButtonsCount - 1 do
|
|
begin
|
|
R := Rect(0, 0, AColumnWidth, MaxInt);
|
|
ACaption := Properties.Items[I].Caption;
|
|
if Properties.WordWrap and (ACaption <> '') then
|
|
begin
|
|
ACanvas.TextExtent(ACaption, R, AFlags);
|
|
AButtonHeight := R.Bottom - R.Top + ASizeCorrection.cy;
|
|
if AMaxButtonHeight < AButtonHeight then
|
|
AMaxButtonHeight := AButtonHeight;
|
|
end;
|
|
end;
|
|
Result.cy := AMaxButtonHeight * AButtonsPerColumn;
|
|
if not IsInplace then
|
|
begin
|
|
R := GetClientExtent(ACanvas, nil);
|
|
Result.cy := Result.cy + R.Top + R.Bottom;
|
|
end;
|
|
end;
|
|
end else
|
|
begin
|
|
if AButtonsCount = 0 then
|
|
begin
|
|
Result.cx := 0;
|
|
Result.cy := ACanvas.TextHeight('Zg') + ASizeCorrection.cy;
|
|
end else
|
|
begin
|
|
AMaxColumnWidth := 0;
|
|
AButtonsPerColumn := Properties.GetButtonsPerColumn;
|
|
for I := 0 to AButtonsCount - 1 do
|
|
begin
|
|
ATextWidth := ACanvas.TextWidth(Properties.Items[I].Caption);
|
|
if ATextWidth > AMaxColumnWidth then
|
|
AMaxColumnWidth := ATextWidth;
|
|
end;
|
|
Result.cx := (AMaxColumnWidth + AEditMetrics.ColumnWidthCorrection + AEditMetrics.ButtonSize.cx) *
|
|
AColumnsCount + AEditMetrics.ColumnOffset * (AColumnsCount - 1) + AEditMetrics.WidthCorrection;
|
|
if ADefaultButtonHeight > AEditMetrics.ButtonSize.cy then
|
|
Result.cy := ADefaultButtonHeight
|
|
else
|
|
Result.cy := AEditMetrics.ButtonSize.cy;
|
|
Result.cy := Result.cy * AButtonsPerColumn;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
class function TcxButtonGroupViewData.IsButtonNativeStyle(
|
|
ALookAndFeel: TcxLookAndFeel): Boolean;
|
|
begin
|
|
Result := AreVisualStylesMustBeUsed(ALookAndFeel.NativeStyle, totButton);
|
|
end;
|
|
|
|
procedure TcxButtonGroupViewData.CalculateButtonPositions(ACanvas: TcxCanvas;
|
|
AViewInfo: TcxCustomEditViewInfo);
|
|
var
|
|
AButtonsCount, AButtonsPerColumn, AButtonHeight, AButtonWidth, AClientHeight,
|
|
AColumnsCount, ATopOffset, I: Integer;
|
|
AButtonViewInfo: TcxGroupBoxButtonViewInfo;
|
|
AClientExtent: TRect;
|
|
AEditMetrics: TcxEditMetrics;
|
|
begin
|
|
AButtonsCount := Properties.Items.Count;
|
|
AColumnsCount := Properties.GetColumnCount;
|
|
AButtonsPerColumn := Properties.GetButtonsPerColumn;
|
|
AClientExtent := GetClientExtent(ACanvas, AViewInfo);
|
|
GetEditMetrics(False, nil, AEditMetrics);
|
|
AButtonWidth := (Bounds.Right - Bounds.Left - (AClientExtent.Left +
|
|
AClientExtent.Right) + AEditMetrics.ClientWidthCorrection -
|
|
AEditMetrics.ColumnOffset * (AColumnsCount - 1)) div AColumnsCount;
|
|
AClientHeight := Bounds.Bottom - Bounds.Top - AClientExtent.Top - AClientExtent.Bottom;
|
|
|
|
ATopOffset := Bounds.Top + AClientExtent.Top + (AClientHeight mod AButtonsPerColumn) div 2;
|
|
|
|
AButtonHeight := AClientHeight div AButtonsPerColumn;
|
|
|
|
for I := 0 to AButtonsCount - 1 do
|
|
begin
|
|
AButtonViewInfo := TcxGroupBoxButtonViewInfo(AViewInfo.ButtonsInfo[I]);
|
|
AButtonViewInfo.Bounds.Left := Bounds.Left + AClientExtent.Left +
|
|
AButtonViewInfo.Column * (AButtonWidth + AEditMetrics.ColumnOffset) +
|
|
AEditMetrics.ClientLeftBoundCorrection;
|
|
AButtonViewInfo.Bounds.Top := ATopOffset + AButtonViewInfo.Row * AButtonHeight;
|
|
AButtonViewInfo.Bounds.Right := AButtonViewInfo.Bounds.Left + AButtonWidth;
|
|
AButtonViewInfo.Bounds.Bottom := AButtonViewInfo.Bounds.Top + AButtonHeight;
|
|
AButtonViewInfo.VisibleBounds := AButtonViewInfo.Bounds;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxButtonGroupViewData.CalculateButtonViewInfos(AViewInfo: TcxCustomEditViewInfo);
|
|
|
|
function GetButtonStyle: TcxEditButtonStyle;
|
|
const
|
|
AButtonInplaceStyleMap: array[TcxLookAndFeelKind] of TcxEditButtonStyle =
|
|
(btsFlat, bts3D, btsUltraFlat,
|
|
btsOffice11);
|
|
AButtonStyleMap: array [TcxEditBorderStyle] of TcxEditButtonStyle =
|
|
(bts3D, btsFlat, btsFlat, btsFlat, bts3D, btsUltraFlat,
|
|
btsOffice11);
|
|
begin
|
|
if IsInplace then
|
|
Result := AButtonInplaceStyleMap[Style.LookAndFeel.Kind]
|
|
else
|
|
case Style.BorderStyle of
|
|
ebsUltraFlat:
|
|
Result := btsUltraFlat;
|
|
ebsOffice11:
|
|
Result := btsOffice11;
|
|
else
|
|
Result := AButtonStyleMap[AViewInfo.BorderStyle];
|
|
end;
|
|
end;
|
|
|
|
var
|
|
AButtonsCount, AButtonsPerColumn, I: Integer;
|
|
AButtonStyle: TcxEditButtonStyle;
|
|
AButtonViewInfo: TcxGroupBoxButtonViewInfo;
|
|
begin
|
|
AButtonStyle := GetButtonStyle;
|
|
AButtonsCount := Properties.Items.Count;
|
|
AButtonsPerColumn := Properties.GetButtonsPerColumn;
|
|
|
|
for I := 0 to AButtonsCount - 1 do
|
|
begin
|
|
AButtonViewInfo := TcxGroupBoxButtonViewInfo(AViewInfo.ButtonsInfo[I]);
|
|
with AButtonViewInfo do
|
|
begin
|
|
HasBackground := AViewInfo.HasBackground;
|
|
Data.Style := AButtonStyle;
|
|
Caption := Properties.FItems[I].Caption;
|
|
Column := I div AButtonsPerColumn;
|
|
Row := I mod AButtonsPerColumn;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxButtonGroupViewData.GetDrawTextFlags: Integer;
|
|
begin
|
|
Result := cxAlignLeft or cxAlignVCenter or cxShowPrefix;
|
|
if (epoAutoHeight in PaintOptions) and Properties.WordWrap then
|
|
begin
|
|
Result := Result or cxDontClip;
|
|
Result := Result or cxWordBreak;
|
|
end
|
|
else
|
|
Result := Result or cxSingleLine;
|
|
end;
|
|
|
|
function TcxButtonGroupViewData.GetCaptionRectExtent: TRect;
|
|
begin
|
|
Result := cxEmptyRect;
|
|
end;
|
|
|
|
function TcxButtonGroupViewData.GetProperties: TcxCustomButtonGroupProperties;
|
|
begin
|
|
Result := TcxCustomButtonGroupProperties(FProperties);
|
|
end;
|
|
|
|
{ TcxCustomGroupBoxProperties }
|
|
|
|
class function TcxCustomGroupBoxProperties.GetContainerClass: TcxContainerClass;
|
|
begin
|
|
Result := TcxCustomGroupBox;
|
|
end;
|
|
|
|
class function TcxCustomGroupBoxProperties.GetViewInfoClass: TcxContainerViewInfoClass;
|
|
begin
|
|
Result := TcxGroupBoxViewInfo;
|
|
end;
|
|
|
|
class function TcxCustomGroupBoxProperties.GetViewDataClass: TcxCustomEditViewDataClass;
|
|
begin
|
|
Result := TcxGroupBoxViewData;
|
|
end;
|
|
|
|
{ TcxButtonGroupItem }
|
|
|
|
constructor TcxButtonGroupItem.Create(Collection: TCollection);
|
|
begin
|
|
if Assigned(Collection) then
|
|
Collection.BeginUpdate;
|
|
try
|
|
inherited Create(Collection);
|
|
FEnabled := True;
|
|
DoChanged(Collection, copAdd);
|
|
finally
|
|
if Assigned(Collection) then
|
|
Collection.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
destructor TcxButtonGroupItem.Destroy;
|
|
var
|
|
ACollection: TCollection;
|
|
AIndex: Integer;
|
|
begin
|
|
ACollection := Collection;
|
|
if not IsCollectionDestroying then
|
|
AIndex := Index
|
|
else
|
|
AIndex := -1;
|
|
if Assigned(ACollection) then
|
|
ACollection.BeginUpdate;
|
|
try
|
|
inherited Destroy;
|
|
DoChanged(ACollection, copDelete, AIndex);
|
|
finally
|
|
if Assigned(ACollection) then
|
|
ACollection.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxButtonGroupItem.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxButtonGroupItem then
|
|
with TcxButtonGroupItem(Source) do
|
|
begin
|
|
Self.Caption := Caption;
|
|
Self.Enabled := Enabled;
|
|
Self.Tag := Tag;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TcxButtonGroupItem.GetCaption: TCaption;
|
|
begin
|
|
Result := FCaption;
|
|
end;
|
|
|
|
procedure TcxButtonGroupItem.DoChanged(ACollection: TCollection;
|
|
ACollectionOperation: TcxCollectionOperation; AIndex: Integer = -1);
|
|
begin
|
|
if Assigned(ACollection) then
|
|
if AIndex = -1 then
|
|
TcxButtonGroupItems(ACollection).InternalNotify(Self, AIndex, ACollectionOperation)
|
|
else
|
|
TcxButtonGroupItems(ACollection).InternalNotify(nil, AIndex, ACollectionOperation);
|
|
end;
|
|
|
|
function TcxButtonGroupItem.GetIsCollectionDestroying: Boolean;
|
|
begin
|
|
Result := (Collection <> nil) and TcxButtonGroupItems(Collection).IsDestroying;
|
|
end;
|
|
|
|
function TcxButtonGroupItem.IsTagStored: Boolean;
|
|
begin
|
|
Result := FTag <> 0;
|
|
end;
|
|
|
|
procedure TcxButtonGroupItem.SetCaption(const Value: TCaption);
|
|
begin
|
|
if Value <> FCaption then
|
|
begin
|
|
FCaption := Value;
|
|
DoChanged(Collection, copChanged);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxButtonGroupItem.SetEnabled(Value: Boolean);
|
|
begin
|
|
if Value <> FEnabled then
|
|
begin
|
|
FEnabled := Value;
|
|
DoChanged(Collection, copChanged);
|
|
end;
|
|
end;
|
|
|
|
{ TcxButtonGroupItems }
|
|
|
|
destructor TcxButtonGroupItems.Destroy;
|
|
begin
|
|
FIsDestroying := True;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxButtonGroupItems.InternalNotify(AItem: TcxButtonGroupItem;
|
|
AItemIndex: Integer; AItemOperation: TcxCollectionOperation);
|
|
begin
|
|
if TcxCustomEditProperties(GetOwner).ChangedLocked or IsDestroying then
|
|
Exit;
|
|
if AItem <> nil then
|
|
FChangedItemIndex := AItem.Index
|
|
else
|
|
FChangedItemIndex := AItemIndex;
|
|
FChangedItemOperation := AItemOperation;
|
|
FItemChanged := True;
|
|
try
|
|
TcxCustomEditProperties(GetOwner).Changed;
|
|
finally
|
|
FItemChanged := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxButtonGroupItems.Update(Item: TCollectionItem);
|
|
begin
|
|
TcxCustomEditProperties(GetOwner).Changed;
|
|
end;
|
|
|
|
function TcxButtonGroupItems.GetItem(Index: Integer): TcxButtonGroupItem;
|
|
begin
|
|
Result := TcxButtonGroupItem(inherited Items[Index]);
|
|
end;
|
|
|
|
procedure TcxButtonGroupItems.SetItem(Index: Integer; Value: TcxButtonGroupItem);
|
|
begin
|
|
inherited Items[Index] := Value;
|
|
end;
|
|
|
|
function TcxButtonGroupItems.QueryInterface(const IID: TGUID; out Obj): HResult;
|
|
begin
|
|
if GetInterface(IID, Obj) then
|
|
Result := S_OK
|
|
else
|
|
Result := E_NOINTERFACE;
|
|
end;
|
|
|
|
function TcxButtonGroupItems._AddRef: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TcxButtonGroupItems._Release: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TcxButtonGroupItems.CheckItemsGetCaption(Index: Integer): string;
|
|
begin
|
|
Result := TcxButtonGroupItem(Items[Index]).Caption;
|
|
end;
|
|
|
|
function TcxButtonGroupItems.CheckItemsGetCount: Integer;
|
|
begin
|
|
Result := Count;
|
|
end;
|
|
|
|
{ TcxCustomButtonGroupProperties }
|
|
|
|
constructor TcxCustomButtonGroupProperties.Create(AOwner: TPersistent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FColumns := 1;
|
|
FItems := CreateItems;
|
|
end;
|
|
|
|
destructor TcxCustomButtonGroupProperties.Destroy;
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
FreeAndNil(FItems);
|
|
finally
|
|
EndUpdate(False);
|
|
end;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroupProperties.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxCustomButtonGroupProperties then
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
inherited Assign(Source);
|
|
with Source as TcxCustomButtonGroupProperties do
|
|
begin
|
|
Self.Columns := Columns;
|
|
Self.Items := Items;
|
|
Self.WordWrap := WordWrap;
|
|
end;
|
|
finally
|
|
EndUpdate;
|
|
end
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TcxCustomButtonGroupProperties.CreatePreviewProperties: TcxCustomEditProperties;
|
|
const
|
|
AItemCaptions: array [0..2] of string = ('A', 'B', 'C');
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := inherited CreatePreviewProperties;
|
|
for I := 0 to High(AItemCaptions) do
|
|
TcxButtonGroupItem(TcxCustomButtonGroupProperties(Result).Items.Add).Caption := AItemCaptions[I];
|
|
TcxCustomButtonGroupProperties(Result).Columns := 3;
|
|
end;
|
|
|
|
class function TcxCustomButtonGroupProperties.GetContainerClass: TcxContainerClass;
|
|
begin
|
|
Result := TcxCustomButtonGroup;
|
|
end;
|
|
|
|
function TcxCustomButtonGroupProperties.GetSpecialFeatures: TcxEditSpecialFeatures;
|
|
begin
|
|
Result := inherited GetSpecialFeatures + [esfMinSize];
|
|
end;
|
|
|
|
function TcxCustomButtonGroupProperties.GetSupportedOperations: TcxEditSupportedOperations;
|
|
begin
|
|
Result := [esoAlwaysHotTrack, esoAutoHeight, esoEditing, esoFiltering,
|
|
esoShowingCaption, esoSorting, esoTransparency];
|
|
if Items.Count > 0 then
|
|
Include(Result, esoHotTrack);
|
|
end;
|
|
|
|
class function TcxCustomButtonGroupProperties.GetViewInfoClass: TcxContainerViewInfoClass;
|
|
begin
|
|
Result := TcxButtonGroupViewInfo;
|
|
end;
|
|
|
|
class function TcxCustomButtonGroupProperties.GetViewDataClass: TcxCustomEditViewDataClass;
|
|
begin
|
|
Result := TcxButtonGroupViewData;
|
|
end;
|
|
|
|
function TcxCustomButtonGroupProperties.GetColumnCount: Integer;
|
|
var
|
|
AButtonCount, AButtonsPerColumn: Integer;
|
|
begin
|
|
Result := Columns;
|
|
AButtonCount := Items.Count;
|
|
if Result > AButtonCount then
|
|
Result := AButtonCount;
|
|
if AButtonCount > 0 then
|
|
begin
|
|
if Result = 0 then
|
|
Result := 1;
|
|
AButtonsPerColumn := (AButtonCount + Result - 1) div Result;
|
|
Result := (AButtonCount + AButtonsPerColumn - 1) div AButtonsPerColumn;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomButtonGroupProperties.CreateItems: TcxButtonGroupItems;
|
|
begin
|
|
Result := TcxButtonGroupItems.Create(Self, TcxButtonGroupItem);
|
|
end;
|
|
|
|
function TcxCustomButtonGroupProperties.GetButtonsPerColumn: Integer;
|
|
var
|
|
AColumnsCount: Integer;
|
|
begin
|
|
AColumnsCount := GetColumnCount;
|
|
Result := (Items.Count + AColumnsCount - 1) div AColumnsCount;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroupProperties.SetColumns(Value: Integer);
|
|
begin
|
|
if Value < 1 then
|
|
Value := 1;
|
|
if Value <> FColumns then
|
|
begin
|
|
FColumns := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroupProperties.SetItems(Value: TcxButtonGroupItems);
|
|
begin
|
|
FItems.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroupProperties.SetWordWrap(Value: Boolean);
|
|
begin
|
|
if Value <> FWordWrap then
|
|
begin
|
|
FWordWrap := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
{ TcxCustomGroupBox }
|
|
|
|
{$IFDEF CBUILDER10}
|
|
constructor TcxCustomGroupBox.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
destructor TcxCustomGroupBox.Destroy;
|
|
begin
|
|
FreeAndNil(FCaptionFont);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
class function TcxCustomGroupBox.GetPropertiesClass: TcxCustomEditPropertiesClass;
|
|
begin
|
|
Result := TcxCustomGroupBoxProperties;
|
|
end;
|
|
|
|
procedure TcxCustomGroupBox.CalculateVisibleCaption;
|
|
begin
|
|
if IsVerticalText then
|
|
FVisibleCaption := RemoveAccelChars(Caption)
|
|
else
|
|
FVisibleCaption := Caption;
|
|
end;
|
|
|
|
function TcxCustomGroupBox.GetColor: TColor;
|
|
begin
|
|
Result := Style.Color;
|
|
end;
|
|
|
|
function TcxCustomGroupBox.GetFont: TFont;
|
|
begin
|
|
Result := Style.GetVisibleFont;
|
|
end;
|
|
|
|
procedure TcxCustomGroupBox.SetAlignment(Value: TcxCaptionAlignment);
|
|
begin
|
|
if FAlignment <> Value then
|
|
begin
|
|
FAlignment := Value;
|
|
CalculateCaptionFont;
|
|
CalculateVisibleCaption;
|
|
ShortRefreshContainer(False);
|
|
Realign;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomGroupBox.SetColor(Value: TColor);
|
|
begin
|
|
Style.Color := Value;
|
|
end;
|
|
|
|
procedure TcxCustomGroupBox.SetFont(Value: TFont);
|
|
begin
|
|
Style.Font := Value;
|
|
end;
|
|
|
|
{$IFNDEF DELPHI7}
|
|
procedure TcxCustomGroupBox.WMPrintClient(var Message: TMessage);
|
|
begin
|
|
if (Message.Result <> 1) and
|
|
((Message.LParam and PRF_CHECKVISIBLE = 0) or Visible) then
|
|
PaintHandler(TWMPaint(Message))
|
|
else
|
|
inherited;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TcxCustomGroupBox.CMDialogChar(var Message: TCMDialogChar);
|
|
begin
|
|
with Message do
|
|
if IsAccel(CharCode, Caption) and CanFocus then
|
|
begin
|
|
FIsAccelCharHandling := True;
|
|
try
|
|
SelectFirst;
|
|
Result := 1;
|
|
finally
|
|
FIsAccelCharHandling := False;
|
|
end;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
procedure TcxCustomGroupBox.LookAndFeelChanged(Sender: TcxLookAndFeel;
|
|
AChangedValues: TcxLookAndFeelValues);
|
|
begin
|
|
inherited LookAndFeelChanged(Sender, AChangedValues);
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TcxCustomGroupBox.AdjustClientRect(var Rect: TRect);
|
|
var
|
|
AViewData: TcxCustomEditViewData;
|
|
begin
|
|
if IsDestroying then
|
|
Exit;
|
|
AViewData := TcxCustomEditViewData(CreateViewData);
|
|
try
|
|
InitializeViewData(AViewData);
|
|
Rect := GetControlRect(Self);
|
|
ExtendRect(Rect, AViewData.GetClientExtent(Canvas, ViewInfo));
|
|
finally
|
|
FreeAndNil(AViewData);
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomGroupBox.CanAutoSize: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxCustomGroupBox.CanFocusOnClick: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TcxCustomGroupBox.ContainerStyleChanged(Sender: TObject);
|
|
begin
|
|
CalculateCaptionFont;
|
|
inherited ContainerStyleChanged(Sender);
|
|
end;
|
|
|
|
function TcxCustomGroupBox.DefaultParentColor: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TcxCustomGroupBox.FontChanged;
|
|
begin
|
|
inherited FontChanged;
|
|
Realign;
|
|
end;
|
|
|
|
function TcxCustomGroupBox.GetShadowBounds: TRect;
|
|
begin
|
|
Result := inherited GetShadowBounds;
|
|
case Alignment of
|
|
alTopLeft, alTopCenter, alTopRight:
|
|
Result.Top := 0;
|
|
alBottomLeft, alBottomCenter, alBottomRight:
|
|
Result.Bottom := Height;
|
|
alLeftTop, alLeftCenter, alLeftBottom:
|
|
Result.Left := 0;
|
|
alRightTop, alRightCenter, alRightBottom:
|
|
Result.Right := Width;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomGroupBox.Initialize;
|
|
begin
|
|
inherited Initialize;
|
|
ControlStyle := ControlStyle + [csAcceptsControls, csCaptureMouse, csClickEvents];
|
|
SetBounds(Left, Top, 185, 105);
|
|
FCaptionFont := TFont.Create;
|
|
CalculateCaptionFont;
|
|
TabStop := False;
|
|
end;
|
|
|
|
function TcxCustomGroupBox.InternalGetActiveStyle: TcxContainerStyle;
|
|
begin
|
|
if csDisabled in ViewInfo.ContainerState then
|
|
Result := FStyles.StyleDisabled
|
|
else
|
|
Result := FStyles.Style;
|
|
end;
|
|
|
|
function TcxCustomGroupBox.InternalGetNotPublishedStyleValues: TcxEditStyleValues;
|
|
begin
|
|
Result := inherited InternalGetNotPublishedStyleValues;
|
|
Include(Result, svHotTrack);
|
|
end;
|
|
|
|
function TcxCustomGroupBox.IsContainerClass: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxCustomGroupBox.IsNativeBackground: Boolean;
|
|
begin
|
|
Result := IsNativeStyle and ParentBackground and not IsInplace and
|
|
not Transparent;
|
|
end;
|
|
|
|
procedure TcxCustomGroupBox.TextChanged;
|
|
begin
|
|
inherited TextChanged;
|
|
CalculateVisibleCaption;
|
|
ShortRefreshContainer(False);
|
|
end;
|
|
|
|
procedure TcxCustomGroupBox.AdjustCanvasFontSettings(ACanvas: TcxCanvas);
|
|
const
|
|
NativeState: array[Boolean] of Integer = (GBS_DISABLED, GBS_NORMAL);
|
|
var
|
|
AColor: TColorRef;
|
|
ATextColor: TColor;
|
|
ATheme: TdxTheme;
|
|
begin
|
|
with ACanvas do
|
|
begin
|
|
Font := FCaptionFont;
|
|
if IsNativeStyle then
|
|
begin
|
|
ATheme := OpenTheme(totButton);
|
|
GetThemeColor(ATheme, BP_GROUPBOX, NativeState[Enabled], TMT_TEXTCOLOR, AColor);
|
|
Font.Color := AColor;
|
|
end;
|
|
if ViewInfo.Painter <> nil then
|
|
begin
|
|
ATextColor := ViewInfo.Painter.GroupBoxTextColor(
|
|
cxGroupBoxAlignment2GroupBoxCaption(Alignment));
|
|
if ATextColor <> clDefault then
|
|
Font.Color := ATextColor;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomGroupBox.CalculateCaptionFont;
|
|
var
|
|
AFontEscapement: Longint;
|
|
ALogFont: TLogFont;
|
|
ATextMetric : TTextMetric;
|
|
begin
|
|
if IsInplace then
|
|
Exit;
|
|
FCaptionFont.Assign(ActiveStyle.GetVisibleFont);
|
|
if IsVerticalText then
|
|
begin
|
|
cxScreenCanvas.Font := FCaptionFont;
|
|
GetTextMetrics(cxScreenCanvas.Handle, ATextMetric);
|
|
if ATextMetric.tmPitchAndFamily and TMPF_TRUETYPE = 0 then
|
|
FCaptionFont.Name := 'Arial';
|
|
|
|
if FAlignment in [alLeftTop, alLeftCenter, alLeftBottom] then
|
|
AFontEscapement := 900
|
|
else
|
|
AFontEscapement := 2700;
|
|
cxGetFontData(FCaptionFont.Handle, ALogFont);
|
|
if AFontEscapement <> ALogFont.lfEscapement then
|
|
begin
|
|
ALogFont.lfEscapement := AFontEscapement;
|
|
ALogFont.lfOrientation := AFontEscapement;
|
|
ALogFont.lfOutPrecision := OUT_TT_ONLY_PRECIS;
|
|
FCaptionFont.Handle := CreateFontIndirect(ALogFont);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomGroupBox.GetCaptionDrawingFlags: Integer;
|
|
begin
|
|
Result := DrawTextBiDiModeFlags(DT_SINGLELINE);
|
|
if IsVerticalText then
|
|
Result := Result or DT_NOPREFIX;
|
|
end;
|
|
|
|
function TcxCustomGroupBox.IsVerticalText: Boolean;
|
|
begin
|
|
Result := FAlignment in [alLeftTop, alLeftCenter, alLeftBottom, alRightTop,
|
|
alRightCenter, alRightBottom];
|
|
end;
|
|
|
|
{ TcxCustomButtonGroup }
|
|
|
|
destructor TcxCustomButtonGroup.Destroy;
|
|
begin
|
|
SetButtonCount(0);
|
|
FreeAndNil(FButtons);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.ActivateByMouse(Shift: TShiftState; X, Y: Integer;
|
|
var AEditData: TcxCustomEditData);
|
|
var
|
|
P: TPoint;
|
|
AButtonIndex: Integer;
|
|
begin
|
|
Activate(AEditData);
|
|
P := Parent.ClientToScreen(Point(X, Y));
|
|
P := ScreenToClient(P);
|
|
AButtonIndex := GetButtonIndexAt(P);
|
|
if AButtonIndex <> -1 then
|
|
begin
|
|
with ViewInfo.ButtonsInfo[AButtonIndex].Bounds do
|
|
begin
|
|
P.X := (Right - Left) div 2;
|
|
P.Y := (Bottom - Top) div 2;
|
|
end;
|
|
if ssLeft in Shift then
|
|
SendMessage(TWinControl(FButtons[AButtonIndex]).Handle, WM_LBUTTONDOWN,
|
|
ShiftStateToKeys(Shift), P.Y shl 16 + P.X)
|
|
else
|
|
SendMessage(TWinControl(FButtons[AButtonIndex]).Handle, WM_LBUTTONUP,
|
|
ShiftStateToKeys(Shift), P.Y shl 16 + P.X);
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomButtonGroup.Focused: Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := inherited Focused;
|
|
if not Result and not FIsCreating then
|
|
for I := 0 to FButtons.Count - 1 do
|
|
if TWinControl(FButtons[I]).Focused then
|
|
begin
|
|
Result := True;
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
class function TcxCustomButtonGroup.GetPropertiesClass: TcxCustomEditPropertiesClass;
|
|
begin
|
|
Result := TcxCustomButtonGroupProperties;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.GetTabOrderList(List: TList);
|
|
begin
|
|
if IsInplace and Visible then
|
|
List.Remove(Parent);
|
|
end;
|
|
|
|
function TcxCustomButtonGroup.IsButtonNativeStyle: Boolean;
|
|
begin
|
|
Result := TcxButtonGroupViewDataClass(Properties.GetViewDataClass).IsButtonNativeStyle(Style.LookAndFeel);
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.PropertiesChanged(Sender: TObject);
|
|
begin
|
|
if not (csReading in ComponentState) then
|
|
UpdateButtons;
|
|
inherited PropertiesChanged(Sender);
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.ReadState(Reader: TReader);
|
|
begin
|
|
inherited ReadState(Reader);
|
|
UpdateButtons;
|
|
SynchronizeDisplayValue;
|
|
end;
|
|
|
|
function TcxCustomButtonGroup.CanAutoSize: Boolean;
|
|
begin
|
|
Result := not IsInplace and AutoSize;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.ContainerStyleChanged(Sender: TObject);
|
|
begin
|
|
inherited ContainerStyleChanged(Sender);
|
|
if not FIsCreating then
|
|
UpdateButtons;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.CursorChanged;
|
|
begin
|
|
UpdateButtons;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.DoEditKeyDown(var Key: Word; Shift: TShiftState);
|
|
var
|
|
AButtonsInColumn, AButtonsPerColumn: Integer;
|
|
AFocusedButtonIndex: Integer;
|
|
AColumn, ARow: Integer;
|
|
begin
|
|
AFocusedButtonIndex := GetFocusedButtonIndex;
|
|
if AFocusedButtonIndex = -1 then
|
|
Exit;
|
|
AButtonsPerColumn := ActiveProperties.GetButtonsPerColumn;
|
|
AButtonsInColumn := AButtonsPerColumn;
|
|
with TcxGroupBoxButtonViewInfo(ViewInfo.ButtonsInfo[AFocusedButtonIndex]) do
|
|
begin
|
|
AColumn := Column;
|
|
ARow := Row;
|
|
end;
|
|
if AFocusedButtonIndex - ARow + AButtonsInColumn - 1 >= ActiveProperties.Items.Count then
|
|
AButtonsInColumn := ActiveProperties.Items.Count - (AFocusedButtonIndex - ARow);
|
|
case Key of
|
|
VK_DOWN:
|
|
if ARow < AButtonsInColumn - 1 then
|
|
begin
|
|
TWinControl(FButtons[AFocusedButtonIndex + 1]).SetFocus;
|
|
Key := 0;
|
|
end;
|
|
VK_LEFT:
|
|
if AColumn > 0 then
|
|
begin
|
|
TWinControl(FButtons[AFocusedButtonIndex - AButtonsPerColumn]).SetFocus;
|
|
Key := 0;
|
|
end;
|
|
VK_RIGHT:
|
|
if AFocusedButtonIndex + AButtonsPerColumn < FButtons.Count then
|
|
begin
|
|
TWinControl(FButtons[AFocusedButtonIndex + AButtonsPerColumn]).SetFocus;
|
|
Key := 0;
|
|
end;
|
|
VK_UP:
|
|
if ARow > 0 then
|
|
begin
|
|
TWinControl(FButtons[AFocusedButtonIndex - 1]).SetFocus;
|
|
Key := 0;
|
|
end
|
|
end;
|
|
inherited DoEditKeyDown(Key, Shift);
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.EnabledChanged;
|
|
begin
|
|
inherited EnabledChanged;
|
|
UpdateButtons;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.Initialize;
|
|
begin
|
|
inherited Initialize;
|
|
FButtons := TList.Create;
|
|
AutoSize := False;
|
|
TabStop := True;
|
|
end;
|
|
|
|
function TcxCustomButtonGroup.IsButtonDC(ADC: THandle): Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := False;
|
|
for I := 0 to InternalButtons.Count - 1 do
|
|
if GetButtonDC(I) = ADC then
|
|
begin
|
|
Result := True;
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomButtonGroup.IsContainerClass: Boolean;
|
|
begin
|
|
Result := FIsAccelCharHandling;
|
|
end;
|
|
|
|
function TcxCustomButtonGroup.RefreshContainer(const P: TPoint;
|
|
Button: TcxMouseButton; Shift: TShiftState; AIsMouseEvent: Boolean): Boolean;
|
|
begin
|
|
Result := inherited RefreshContainer(P, Button, Shift, AIsMouseEvent);
|
|
ArrangeButtons;
|
|
SynchronizeButtonsStyle;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.CreateHandle;
|
|
begin
|
|
inherited CreateHandle;
|
|
UpdateButtons;
|
|
SynchronizeDisplayValue;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.ArrangeButtons;
|
|
var
|
|
AButtonViewInfo: TcxGroupBoxButtonViewInfo;
|
|
I: Integer;
|
|
R: TRect;
|
|
begin
|
|
for I := 0 to FButtons.Count - 1 do
|
|
with TWinControl(FButtons[I]) do
|
|
begin
|
|
AButtonViewInfo := TcxGroupBoxButtonViewInfo(ViewInfo.ButtonsInfo[I]);
|
|
R := AButtonViewInfo.Bounds;
|
|
SetBounds(R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top);
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomButtonGroup.GetButtonIndexAt(const P: TPoint): Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := -1;
|
|
for I := 0 to ActiveProperties.Items.Count - 1 do
|
|
if PtInRect(ViewInfo.ButtonsInfo[I].Bounds, P) then
|
|
begin
|
|
Result := I;
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomButtonGroup.GetFocusedButtonIndex: Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := -1;
|
|
for I := 0 to ActiveProperties.Items.Count - 1 do
|
|
if TWinControl(FButtons[I]).Focused then
|
|
begin
|
|
Result := I;
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.InitButtonInstance(AButton: TWinControl);
|
|
begin
|
|
TControlAccess(AButton).ParentShowHint := False;
|
|
AButton.Parent := Self;
|
|
|
|
TControlAccess(AButton).OnDragDrop := DoButtonDragDrop;
|
|
TControlAccess(AButton).OnDragOver := DoButtonDragOver;
|
|
TWinControlAccess(AButton).OnKeyDown := DoButtonKeyDown;
|
|
TWinControlAccess(AButton).OnKeyPress := DoButtonKeyPress;
|
|
TWinControlAccess(AButton).OnKeyUp := DoButtonKeyUp;
|
|
TControlAccess(AButton).OnMouseDown := DoButtonMouseDown;
|
|
TControlAccess(AButton).OnMouseMove := DoButtonMouseMove;
|
|
TControlAccess(AButton).OnMouseUp := DoButtonMouseUp;
|
|
{$IFDEF DELPHI6}
|
|
TControlAccess(AButton).OnMouseWheel := DoButtonMouseWheel;
|
|
{$ELSE}
|
|
TWinControlAccess(AButton).OnMouseWheel := DoButtonMouseWheel;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.SetButtonCount(Value: Integer);
|
|
begin
|
|
with ActiveProperties.Items do
|
|
if ItemChanged then
|
|
begin
|
|
if ChangedItemOperation = copAdd then
|
|
InitButtonInstance(GetButtonInstance)
|
|
else
|
|
if ChangedItemOperation = copDelete then
|
|
TWinControl(FButtons[ChangedItemIndex]).Free;
|
|
end
|
|
else
|
|
if Value <> FButtons.Count then
|
|
begin
|
|
DisableAlign;
|
|
try
|
|
if Value < FButtons.Count then
|
|
while FButtons.Count > Value do
|
|
TWinControl(FButtons.Last).Free
|
|
else
|
|
while FButtons.Count < Value do
|
|
InitButtonInstance(GetButtonInstance);
|
|
finally
|
|
EnableAlign;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.SynchronizeButtonsStyle;
|
|
var
|
|
AButton: TWinControlAccess;
|
|
ATempFont: TFont;
|
|
I: Integer;
|
|
begin
|
|
ATempFont := TFont.Create;
|
|
try
|
|
for I := 0 to FButtons.Count - 1 do
|
|
begin
|
|
AButton := TWinControlAccess(FButtons[I]);
|
|
AButton.Color := ActiveStyle.Color;
|
|
ATempFont.Assign(Style.GetVisibleFont);
|
|
ATempFont.Color := ActiveStyle.GetVisibleFont.Color;
|
|
AssignFonts(AButton.Font, ATempFont);
|
|
end;
|
|
finally
|
|
ATempFont.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.UpdateButtons;
|
|
var
|
|
AButton: TWinControl;
|
|
I: Integer;
|
|
begin
|
|
SetButtonCount(ActiveProperties.Items.Count);
|
|
ShortRefreshContainer(False);
|
|
for I := 0 to FButtons.Count - 1 do
|
|
begin
|
|
AButton := TWinControl(FButtons[I]);
|
|
AButton.Enabled := Enabled and ActiveProperties.Items[I].Enabled;
|
|
end;
|
|
for I := 0 to FButtons.Count - 1 do
|
|
begin
|
|
AButton := TWinControl(FButtons[I]);
|
|
AButton.Cursor := Cursor;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.DoButtonDragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
begin
|
|
with TWinControl(Sender) do
|
|
Self.DragDrop(Source, Left + X, Top + Y);
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.DoButtonDragOver(Sender, Source: TObject; X, Y: Integer;
|
|
State: TDragState; var Accept: Boolean);
|
|
begin
|
|
with TWinControl(Sender) do
|
|
Self.DragOver(Source, Left + X, Top + Y, State, Accept);
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.DoButtonKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
begin
|
|
KeyDown(Key, Shift);
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.DoButtonKeyPress(Sender: TObject; var Key: Char);
|
|
begin
|
|
KeyPress(Key);
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.DoButtonKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
begin
|
|
KeyUp(Key, Shift);
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.DoButtonMouseDown(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
InnerControlMouseDown := True;
|
|
try
|
|
with TWinControl(Sender) do
|
|
Self.MouseDown(Button, Shift, X + Left, Y + Top);
|
|
finally
|
|
InnerControlMouseDown := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.DoButtonMouseMove(Sender: TObject; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
begin
|
|
with TWinControl(Sender) do
|
|
Self.MouseMove(Shift, X + Left, Y + Top);
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.DoButtonMouseUp(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
with TWinControl(Sender) do
|
|
Self.MouseUp(Button, Shift, X + Left, Y + Top);
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.DoButtonMouseWheel(Sender: TObject; Shift: TShiftState;
|
|
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
|
|
begin
|
|
Handled := False;
|
|
end;
|
|
|
|
function TcxCustomButtonGroup.GetProperties: TcxCustomButtonGroupProperties;
|
|
begin
|
|
Result := TcxCustomButtonGroupProperties(FProperties);
|
|
end;
|
|
|
|
function TcxCustomButtonGroup.GetActiveProperties: TcxCustomButtonGroupProperties;
|
|
begin
|
|
Result := TcxCustomButtonGroupProperties(InternalGetActiveProperties);
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.SetProperties(Value: TcxCustomButtonGroupProperties);
|
|
begin
|
|
FProperties.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxCustomButtonGroup.WMWindowPosChanged(var Message: TWMWindowPosChanged);
|
|
begin
|
|
inherited;
|
|
if not IsDestroying and IsTransparentBackground then
|
|
RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_ALLCHILDREN);
|
|
end;
|
|
|
|
end.
|