Componentes.Terceros.DevExp.../internal/x.42/2/ExpressEditors Library 5/Sources/cxCheckGroup.pas

1328 lines
42 KiB
ObjectPascal

{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressEditors }
{ }
{ Copyright (c) 1998-2009 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSEDITORS AND ALL }
{ ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{********************************************************************}
unit cxCheckGroup;
{$I cxVer.inc}
interface
uses
Windows, Classes, Graphics, Messages, Controls,
dxCore, cxContainer, cxGraphics, cxLookAndFeels,cxEdit, cxGroupBox,
cxCheckBox, cxFilterControlUtils, cxCheckComboBox,
cxLookAndFeelPainters;
type
{ TcxCheckGroupItem }
TcxCheckGroupItem = class(TcxButtonGroupItem)
published
property Caption;
property Enabled;
property Tag;
end;
{ TcxCheckGroupItems }
TcxCheckGroupItems = class(TcxButtonGroupItems)
private
function GetItem(Index: Integer): TcxCheckGroupItem;
procedure SetItem(Index: Integer; Value: TcxCheckGroupItem);
public
function Add: TcxCheckGroupItem;
property Items[Index: Integer]: TcxCheckGroupItem
read GetItem write SetItem; default;
end;
{ TcxCheckGroupButtonViewInfo }
TcxCheckGroupButtonViewInfo = class(TcxGroupBoxButtonViewInfo)
public
State: TcxCheckBoxState;
function GetGlyphRect(ACanvas: TcxCanvas; AGlyphSize: TSize; AAlignment: TLeftRight; AIsPaintCopy: Boolean): TRect; override;
end;
TcxCustomCheckGroup = class;
{ TcxCheckGroupViewInfo }
TcxCheckGroupViewInfo = class(TcxButtonGroupViewInfo)
private
function GetEdit: TcxCustomCheckGroup;
protected
procedure DrawButtonCaption(ACanvas: TcxCanvas;
AButtonViewInfo: TcxGroupBoxButtonViewInfo; const AGlyphRect: TRect); override;
procedure DrawButtonGlyph(ACanvas: TcxCanvas;
AButtonViewInfo: TcxGroupBoxButtonViewInfo; const AGlyphRect: TRect); override;
function GetButtonViewInfoClass: TcxEditButtonViewInfoClass; override;
function IsButtonGlypthTransparent(AButtonViewInfo: TcxGroupBoxButtonViewInfo): Boolean; override;
procedure SetOnDrawBackground(AValue: TcxEditDrawBackgroundEvent); override;
public
CheckBorderStyle: TcxEditCheckBoxBorderStyle;
property Edit: TcxCustomCheckGroup read GetEdit;
end;
{ TcxCheckGroupViewData }
TcxCheckGroupViewData = class(TcxButtonGroupViewData)
protected
procedure CalculateButtonNativeState(AViewInfo: TcxCustomEditViewInfo;
AButtonViewInfo: TcxGroupBoxButtonViewInfo); override;
function GetCaptionRectExtent: TRect; override;
procedure GetEditMetrics(AAutoHeight: Boolean; ACanvas: TcxCanvas;
out AMetrics: TcxEditMetrics); override;
public
procedure Calculate(ACanvas: TcxCanvas; const ABounds: TRect; const P: TPoint;
Button: TcxMouseButton; Shift: TShiftState; AViewInfo: TcxCustomEditViewInfo;
AIsMouseEvent: Boolean); override;
procedure EditValueToDrawValue(ACanvas: TcxCanvas; const AEditValue: TcxEditValue;
AViewInfo: TcxCustomEditViewInfo); override;
end;
{ TcxCustomCheckGroupProperties }
TcxCustomCheckGroupProperties = class(TcxCustomButtonGroupProperties)
private
FAllowGrayed: Boolean;
FEditValueFormat: TcxCheckStatesValueFormat;
FGlyph: TBitmap;
FGlyphCount: Integer;
FItemAlignment: TLeftRight;
FOnEditValueToStates: TcxValueToCheckStatesEvent;
FOnStatesToEditValue: TcxCheckStatesToValueEvent;
function GetGlyph: TBitmap;
function GetItems: TcxCheckGroupItems;
procedure GlyphChanged(Sender: TObject);
procedure SetAllowGrayed(Value: Boolean);
procedure SetEditValueFormat(Value: TcxCheckStatesValueFormat);
procedure SetGlyph(Value: TBitmap);
procedure SetGlyphCount(Value: Integer);
procedure SetItemAlignment(Value: TLeftRight);
procedure SetItems(Value: TcxCheckGroupItems);
procedure CheckEditValueFormat;
procedure ItemsChanged(Sender: TObject; AItem: TCollectionItem);
protected
function CreateItems: TcxButtonGroupItems; override;
class function GetViewDataClass: TcxCustomEditViewDataClass; override;
function HasDisplayValue: Boolean; override;
procedure CalculateCheckStatesByEditValue(Sender: TObject;
const AEditValue: TcxEditValue); virtual;
procedure CalculateEditValueByCheckStates(Sender: TObject;
out AEditValue: TcxEditValue); virtual;
public
constructor Create(AOwner: TPersistent); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
function CompareDisplayValues(
const AEditValue1, AEditValue2: TcxEditValue): Boolean; override;
class function GetContainerClass: TcxContainerClass; override;
function GetDisplayText(const AEditValue: TcxEditValue;
AFullText: Boolean = False; AIsInplace: Boolean = True): WideString; override;
class function GetViewInfoClass: TcxContainerViewInfoClass; override;
// !!!
property AllowGrayed: Boolean read FAllowGrayed write SetAllowGrayed
default False;
property EditValueFormat: TcxCheckStatesValueFormat read FEditValueFormat
write SetEditValueFormat default cvfIndices;
property Glyph: TBitmap read GetGlyph write SetGlyph;
property GlyphCount: Integer read FGlyphCount write SetGlyphCount default 6;
property ItemAlignment: TLeftRight read FItemAlignment
write SetItemAlignment default taLeftJustify;
property Items: TcxCheckGroupItems read GetItems write SetItems;
property OnEditValueToStates: TcxValueToCheckStatesEvent
read FOnEditValueToStates write FOnEditValueToStates;
property OnStatesToEditValue: TcxCheckStatesToValueEvent
read FOnStatesToEditValue write FOnStatesToEditValue;
end;
{ TcxCheckGroupProperties }
TcxCheckGroupProperties = class(TcxCustomCheckGroupProperties)
published
property AllowGrayed;
property AssignedValues;
property ClearKey;
property Columns;
property EditValueFormat;
property Glyph;
property GlyphCount;
property ImmediatePost;
property ItemAlignment;
property Items;
property ReadOnly;
property WordWrap;
property OnChange;
property OnEditValueChanged;
property OnEditValueToStates;
property OnStatesToEditValue;
end;
{ TcxCheckGroupCheckButtonViewInfo }
TcxCheckGroupCheckButtonViewInfo = class(TcxCustomCheckBoxViewInfo)
protected
procedure InternalPaint(ACanvas: TcxCanvas); override;
end;
{ TcxCheckGroupButtonProperties }
TcxCheckGroupButtonProperties = class(TcxCheckBoxProperties)
protected
function InternalGetGlyph: TBitmap; override;
function IsEmbeddedEdit: Boolean; override;
public
class function GetViewInfoClass: TcxContainerViewInfoClass; override;
end;
{ TcxCheckGroupButton }
TcxCheckGroupButton = class(TcxCheckBox, IcxContainerInnerControl)
private
FColumn: Integer;
FRow: Integer;
function GetCheckGroup: TcxCustomCheckGroup;
protected
function CanAutoSize: Boolean; override;
procedure DoExit; override;
procedure Initialize; override;
function IsNativeBackground: Boolean; override;
function IsNativeStyle: Boolean; override;
function IsTransparent: Boolean; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure LookAndFeelChanged(Sender: TcxLookAndFeel;
AChangedValues: TcxLookAndFeelValues); override;
procedure WndProc(var Message: TMessage); override;
// IcxContainerInnerControl
function GetControl: TWinControl;
function GetControlContainer: TcxContainer;
procedure CheckTransparentBorder;
property CheckGroup: TcxCustomCheckGroup read GetCheckGroup;
public
destructor Destroy; override;
function ExecuteAction(Action: TBasicAction): Boolean; override;
class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
function UpdateAction(Action: TBasicAction): Boolean; override;
end;
{ TcxCustomCheckGroup }
TcxCustomCheckGroup = class(TcxCustomButtonGroup)
private
FButtonStatesChanging: Boolean;
FFocusedItemIndex: Integer;
FStatesItems: Boolean;
procedure DoButtonChange(Sender: TObject);
procedure DoButtonEditing(Sender: TObject; var CanEdit: Boolean);
procedure DoButtonFocusChanged(Sender: TObject);
function GetActiveProperties: TcxCustomCheckGroupProperties;
function GetButton(Index: Integer): TcxCheckGroupButton;
function GetProperties: TcxCustomCheckGroupProperties;
function GetState(Index: Integer): TcxCheckBoxState;
procedure SetProperties(Value: TcxCustomCheckGroupProperties);
procedure SetState(Index: Integer; Value: TcxCheckBoxState);
protected
procedure ArrangeButtons; override;
function GetButtonDC(AButtonIndex: Integer): THandle; override;
function GetButtonInstance: TWinControl; override;
procedure Initialize; override;
procedure InternalSetEditValue(const Value: TcxEditValue; AValidateEditValue: Boolean); override;
procedure InternalValidateDisplayValue(const ADisplayValue: TcxEditValue); override;
function IsEditValueStored: Boolean; override;
procedure ParentBackgroundChanged; override;
procedure PropertiesChanged(Sender: TObject); override;
procedure SynchronizeButtonsStyle; override;
procedure SynchronizeDisplayValue; override;
procedure SynchronizeModifiedAfterEnter; virtual;
procedure UpdateButtons; override;
function WantNavigationKeys: Boolean; override;
function GetFirstEnabledItemIndex(AStartIndex: Integer): Integer;
property Buttons[Index: Integer]: TcxCheckGroupButton read GetButton;
property InternalButtons;
property StatesItems: Boolean read FStatesItems write FStatesItems stored False;
public
procedure Activate(var AEditData: TcxCustomEditData); override;
class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
procedure GetTabOrderList(List: TList); override;
procedure SetFocus; override;
property ActiveProperties: TcxCustomCheckGroupProperties
read GetActiveProperties;
property Properties: TcxCustomCheckGroupProperties read GetProperties
write SetProperties;
property States[Index: Integer]: TcxCheckBoxState read GetState
write SetState; default;
property Transparent;
end;
{ TcxCheckGroup }
TcxCheckGroup = class(TcxCustomCheckGroup)
private
function GetActiveProperties: TcxCheckGroupProperties;
function GetProperties: TcxCheckGroupProperties;
procedure SetProperties(Value: TcxCheckGroupProperties);
public
class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
property ActiveProperties: TcxCheckGroupProperties read GetActiveProperties;
published
property Align;
property Alignment;
property Anchors;
property Caption;
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property EditValue;
property Enabled;
property ParentBackground;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property Properties: TcxCheckGroupProperties read GetProperties
write SetProperties;
property ShowHint;
property StatesItems;
property Style;
property StyleDisabled;
property StyleFocused;
property StyleHot;
property TabOrder;
property TabStop;
property Transparent;
property Visible;
property OnClick;
property OnContextPopup;
property OnDragDrop;
property OnDragOver;
property OnEditing;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnFocusChanged;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
end;
{ TcxFilterCheckGroupHelper }
TcxFilterCheckGroupHelper = class(TcxFilterChecksHelper)
protected
class function GetEditValueFormat(
AEditProperties: TcxCustomEditProperties): TcxCheckStatesValueFormat; override;
class function GetItems(
AEditProperties: TcxCustomEditProperties): IcxCheckItems; override;
class procedure InitializeItems(AProperties,
AEditProperties: TcxCustomEditProperties); override;
end;
implementation
uses
{$IFDEF DELPHI6}
Variants,
Types,
{$ENDIF}
SysUtils, cxClasses, cxControls, cxVariants, cxExtEditConsts, cxEditUtils,
dxThemeManager, cxEditPaintUtils;
{ TcxCheckGroupItems }
function TcxCheckGroupItems.Add: TcxCheckGroupItem;
begin
Result := TcxCheckGroupItem(inherited Add);
end;
function TcxCheckGroupItems.GetItem(Index: Integer): TcxCheckGroupItem;
begin
Result := TcxCheckGroupItem(inherited Items[Index]);
end;
procedure TcxCheckGroupItems.SetItem(Index: Integer; Value: TcxCheckGroupItem);
begin
inherited Items[Index] := Value;
end;
{ TcxCheckGroupButtonViewInfo }
function TcxCheckGroupButtonViewInfo.GetGlyphRect(ACanvas: TcxCanvas;
AGlyphSize: TSize; AAlignment: TLeftRight; AIsPaintCopy: Boolean): TRect;
procedure CorrectCheckRect(var ACheckRect: TRect);
begin
if AIsPaintCopy then
if AAlignment = taRightJustify then
OffsetRect(ACheckRect, 2, 0)
else
OffsetRect(ACheckRect, -2, 0);
end;
begin
case AAlignment of
taLeftJustify: AAlignment := taRightJustify;
taRightJustify: AAlignment := taLeftJustify;
end;
Result := inherited GetGlyphRect(ACanvas, AGlyphSize, AAlignment, AIsPaintCopy);
CorrectCheckRect(Result);
end;
{ TcxCheckGroupViewInfo }
procedure TcxCheckGroupViewInfo.DrawButtonCaption(ACanvas: TcxCanvas;
AButtonViewInfo: TcxGroupBoxButtonViewInfo; const AGlyphRect: TRect);
function GetCaptionRect(const ACheckRect: TRect): TRect;
begin
Result := AButtonViewInfo.Bounds;
if Alignment = taLeftJustify then
begin
Result.Left := ACheckRect.Right + CaptionExtent.Left;
Dec(Result.Right, CaptionExtent.Right);
end
else
begin
Result.Right := ACheckRect.Left - CaptionExtent.Right;
Inc(Result.Left, CaptionExtent.Left);
end;
end;
begin
DrawCheckBoxText(ACanvas, AButtonViewInfo.Caption, Font, TextColor,
GetCaptionRect(AGlyphRect), DrawTextFlags, Enabled);
end;
procedure TcxCheckGroupViewInfo.DrawButtonGlyph(ACanvas: TcxCanvas;
AButtonViewInfo: TcxGroupBoxButtonViewInfo; const AGlyphRect: TRect);
const
ACheckStateByButtonState: array[TcxEditButtonState] of TcxEditCheckState =
(ecsDisabled, ecsNormal, ecsPressed, ecsHot);
var
ACheckBorderStyle: TcxEditBorderStyle;
AEditProperties: TcxCustomCheckGroupProperties;
begin
if (CheckBorderStyle = ebsFlat) and (AButtonViewInfo.Data.State = ebsSelected) then
ACheckBorderStyle := ebs3D
else
ACheckBorderStyle := CheckBorderStyle;
AEditProperties := TcxCustomCheckGroupProperties(EditProperties);
DrawEditCheck(ACanvas, AGlyphRect, TcxCheckGroupButtonViewInfo(AButtonViewInfo).State,
ACheckStateByButtonState[AButtonViewInfo.Data.State], AEditProperties.Glyph,
AEditProperties.GlyphCount, ACheckBorderStyle, AButtonViewInfo.Data.NativeStyle,
clBtnText, BackgroundColor, not IsBackgroundTransparent, IsDesigning, False, True,
Painter);
end;
function TcxCheckGroupViewInfo.GetButtonViewInfoClass: TcxEditButtonViewInfoClass;
begin
Result := TcxCheckGroupButtonViewInfo;
end;
function TcxCheckGroupViewInfo.IsButtonGlypthTransparent(AButtonViewInfo: TcxGroupBoxButtonViewInfo): Boolean;
begin
Result := IsBackgroundTransparent;
end;
procedure TcxCheckGroupViewInfo.SetOnDrawBackground(AValue: TcxEditDrawBackgroundEvent);
var
I: Integer;
begin
inherited SetOnDrawBackground(AValue);
if Edit <> nil then
for I := 0 to Edit.InternalButtons.Count - 1 do
TcxCheckGroupButton(Edit.InternalButtons[I]).ViewInfo.OnDrawBackground := AValue;
end;
function TcxCheckGroupViewInfo.GetEdit: TcxCustomCheckGroup;
begin
Result := TcxCustomCheckGroup(FEdit);
end;
{ TcxCheckGroupViewData }
procedure TcxCheckGroupViewData.Calculate(ACanvas: TcxCanvas;
const ABounds: TRect; const P: TPoint; Button: TcxMouseButton;
Shift: TShiftState; AViewInfo: TcxCustomEditViewInfo; AIsMouseEvent: Boolean);
const
ABorderStyle: array[TcxLookAndFeelKind] of TcxEditCheckBoxBorderStyle =
(ebsFlat, ebs3D, ebsUltraFlat, ebsOffice11);
begin
inherited Calculate(ACanvas, ABounds, P, Button, Shift, AViewInfo,
AIsMouseEvent);
with TcxCustomCheckGroupProperties(Properties) do
begin
TcxCheckGroupViewInfo(AViewInfo).GlyphSize :=
GetEditCheckSize(ACanvas, IsButtonNativeStyle(Style.LookAndFeel), Glyph,
GlyphCount, AViewInfo.Painter);
TcxCheckGroupViewInfo(AViewInfo).Alignment := ItemAlignment;
end;
TcxCheckGroupViewInfo(AViewInfo).CheckBorderStyle :=
ABorderStyle[Style.LookAndFeel.Kind];
AViewInfo.BackgroundColor := Style.Color;
end;
procedure TcxCheckGroupViewData.EditValueToDrawValue(ACanvas: TcxCanvas;
const AEditValue: TcxEditValue; AViewInfo: TcxCustomEditViewInfo);
var
ASender: TObject;
I: Integer;
begin
with TcxCustomCheckGroupProperties(Properties) do
begin
if IsInplace then
ASender := nil
else
ASender := Edit;
TcxCheckGroupViewInfo(AViewInfo).SetButtonCount(Items.Count);
if PreviewMode then
TcxCheckGroupButtonViewInfo(AViewInfo.ButtonsInfo[0]).State := cbsChecked
else
begin
CalculateCheckStatesByEditValue(ASender, AEditValue);
for I := 0 to Items.Count - 1 do
TcxCheckGroupButtonViewInfo(AViewInfo.ButtonsInfo[I]).State := CheckStates[I];
end;
end;
if epoAutoHeight in PaintOptions then
Include(AViewInfo.PaintOptions, epoAutoHeight);
end;
procedure TcxCheckGroupViewData.CalculateButtonNativeState(AViewInfo: TcxCustomEditViewInfo;
AButtonViewInfo: TcxGroupBoxButtonViewInfo);
begin
end;
function TcxCheckGroupViewData.GetCaptionRectExtent: TRect;
begin
Result.Top := 0;
Result.Bottom := 0;
if TcxCustomCheckGroupProperties(Properties).ItemAlignment = taLeftJustify then
begin
Result.Left := 3;
Result.Right := 2;
end
else
begin
Result.Right := 2;
Result.Left := 2;
end;
end;
procedure TcxCheckGroupViewData.GetEditMetrics(AAutoHeight: Boolean;
ACanvas: TcxCanvas; out AMetrics: TcxEditMetrics);
begin
AMetrics.ClientLeftBoundCorrection := 6 - (5 +
Integer(TcxCustomCheckGroupProperties(Properties).ItemAlignment =
taRightJustify)) * Integer(IsInplace);
AMetrics.ClientWidthCorrection := 5 * Integer(IsInplace) - 6;
AMetrics.ColumnOffset := 6;
if ACanvas = nil then
Exit;
AMetrics.ButtonSize := GetEditCheckSize(ACanvas,
IsButtonNativeStyle(Style.LookAndFeel),
TcxCustomCheckGroupProperties(Properties).FGlyph,
TcxCustomCheckGroupProperties(Properties).GlyphCount,
Style.LookAndFeel.Painter);
with GetCaptionRectExtent do
AMetrics.AutoHeightColumnWidthCorrection := Left + Right;
AMetrics.ColumnWidthCorrection := AMetrics.AutoHeightColumnWidthCorrection;
AMetrics.WidthCorrection := 6 - 5 * Integer(IsInplace);
AMetrics.AutoHeightWidthCorrection := AMetrics.ClientWidthCorrection;
end;
{ TcxCustomCheckGroupProperties }
constructor TcxCustomCheckGroupProperties.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FEditValueFormat := cvfIndices;
FItemAlignment := taLeftJustify;
FGlyphCount := 6;
Items.OnChange := ItemsChanged;
end;
destructor TcxCustomCheckGroupProperties.Destroy;
begin
if FGlyph <> nil then
FreeAndNil(FGlyph);
inherited Destroy;
end;
procedure TcxCustomCheckGroupProperties.Assign(Source: TPersistent);
begin
if Source is TcxCustomCheckGroupProperties then
begin
BeginUpdate;
try
inherited Assign(Source);
with TcxCustomCheckGroupProperties(Source) do
begin
Self.AllowGrayed := AllowGrayed;
Self.ItemAlignment := ItemAlignment;
Self.WordWrap := WordWrap;
Self.Glyph := Glyph;
Self.GlyphCount := GlyphCount;
Self.EditValueFormat := EditValueFormat;
Self.OnEditValueToStates := OnEditValueToStates;
Self.OnStatesToEditValue := OnStatesToEditValue;
end;
finally
EndUpdate;
end
end
else
inherited Assign(Source);
end;
function TcxCustomCheckGroupProperties.CompareDisplayValues(
const AEditValue1, AEditValue2: TcxEditValue): Boolean;
var
ACheckStates: TcxCheckStates;
begin
CalculateCheckStatesByEditValue(nil, AEditValue1);
ACheckStates := Copy(CheckStates);
CalculateCheckStatesByEditValue(nil, AEditValue2);
Result := CompareMem(@ACheckStates[0], @CheckStates[0],
SizeOf(TcxCheckBoxState) * Length(CheckStates));
end;
class function TcxCustomCheckGroupProperties.GetContainerClass: TcxContainerClass;
begin
Result := TcxCheckGroup;
end;
function TcxCustomCheckGroupProperties.GetDisplayText(const AEditValue: TcxEditValue;
AFullText: Boolean = False; AIsInplace: Boolean = True): WideString;
var
ACheckStateNames: array[TcxCheckBoxState] of WideString;
procedure InitCheckStateNames;
begin
ACheckStateNames[cbsUnchecked] :=
cxGetResourceString(@cxSEditCheckGroupUnchecked);
ACheckStateNames[cbsChecked] :=
cxGetResourceString(@cxSEditCheckGroupChecked);
ACheckStateNames[cbsGrayed] :=
cxGetResourceString(@cxSEditCheckGroupGrayed);
end;
var
I: Integer;
begin
CalculateCheckStatesByEditValue(nil, AEditValue);
InitCheckStateNames;
Result := '';
for I := 0 to Items.Count - 1 do
begin
Result := Result + Items[I].Caption +
cxGetResourceString(@cxSEditCheckGroupCaptionStateDelimiter) +
ACheckStateNames[CheckStates[I]];
if I < Items.Count - 1 then
Result := Result + cxGetResourceString(@cxSEditCheckGroupFilterColumnSeparator);
end;
end;
class function TcxCustomCheckGroupProperties.GetViewInfoClass: TcxContainerViewInfoClass;
begin
Result := TcxCheckGroupViewInfo;
end;
function TcxCustomCheckGroupProperties.CreateItems: TcxButtonGroupItems;
begin
Result := TcxCheckGroupItems.Create(Self, TcxCheckGroupItem);
end;
class function TcxCustomCheckGroupProperties.GetViewDataClass: TcxCustomEditViewDataClass;
begin
Result := TcxCheckGroupViewData;
end;
function TcxCustomCheckGroupProperties.HasDisplayValue: Boolean;
begin
Result := True;
end;
procedure TcxCustomCheckGroupProperties.CalculateCheckStatesByEditValue(
Sender: TObject; const AEditValue: TcxEditValue);
begin
if Assigned(OnEditValueToStates) then
begin
SetLength(CheckStates, Items.Count);
OnEditValueToStates(Sender, AEditValue, CheckStates);
end
else
cxCheckBox.CalculateCheckStates(AEditValue, Items, EditValueFormat, CheckStates);
end;
procedure TcxCustomCheckGroupProperties.CalculateEditValueByCheckStates(
Sender: TObject; out AEditValue: TcxEditValue);
begin
if Assigned(OnStatesToEditValue) then
OnStatesToEditValue(Sender, CheckStates, AEditValue)
else
AEditValue := cxCheckBox.CalculateCheckStatesValue(CheckStates, Items, EditValueFormat);
end;
function TcxCustomCheckGroupProperties.GetGlyph: TBitmap;
begin
if FGlyph = nil then
begin
FGlyph := TBitmap.Create;
FGlyph.OnChange := GlyphChanged;
end;
Result := FGlyph;
end;
function TcxCustomCheckGroupProperties.GetItems: TcxCheckGroupItems;
begin
Result := TcxCheckGroupItems(inherited Items);
end;
procedure TcxCustomCheckGroupProperties.GlyphChanged(Sender: TObject);
begin
Changed;
end;
procedure TcxCustomCheckGroupProperties.SetAllowGrayed(Value: Boolean);
begin
if Value <> FAllowGrayed then
begin
FAllowGrayed := Value;
Changed;
end;
end;
procedure TcxCustomCheckGroupProperties.SetEditValueFormat(Value: TcxCheckStatesValueFormat);
begin
if Value <> FEditValueFormat then
begin
FEditValueFormat := Value;
Changed;
CheckEditValueFormat;
end;
end;
procedure TcxCustomCheckGroupProperties.SetGlyph(Value: TBitmap);
begin
if Value = nil then
FreeAndNil(FGlyph)
else
Glyph.Assign(Value);
Changed;
end;
procedure TcxCustomCheckGroupProperties.SetGlyphCount(Value: Integer);
begin
if FGlyphCount <> Value then
begin
FGlyphCount := Value;
if FGlyph <> nil then
Changed;
end;
end;
procedure TcxCustomCheckGroupProperties.SetItemAlignment(Value: TLeftRight);
begin
if Value <> FItemAlignment then
begin
FItemAlignment := Value;
Changed;
end;
end;
procedure TcxCustomCheckGroupProperties.SetItems(Value: TcxCheckGroupItems);
begin
inherited Items.Assign(Value);
end;
procedure TcxCustomCheckGroupProperties.CheckEditValueFormat;
begin
if (EditValueFormat = cvfInteger) and (Items.Count > 64) then
raise EdxException.Create(cxGetResourceString(@cxSCheckControlIncorrectItemCount));
end;
procedure TcxCustomCheckGroupProperties.ItemsChanged(Sender: TObject; AItem: TCollectionItem);
begin
CheckEditValueFormat;
end;
{ TcxCheckGroupCheckButtonViewInfo }
procedure TcxCheckGroupCheckButtonViewInfo.InternalPaint(ACanvas: TcxCanvas);
var
ARect: TRect;
ABitmap: TBitmap;
ABitmapCanvas: TcxCanvas;
begin
if Painter <> nil then
begin
ARect := ClientRect;
ABitmap := cxCreateBitmap(ARect, pf32bit);
ABitmapCanvas := TcxCanvas.Create(ABitmap.Canvas);
try
Painter.DrawGroupBoxBackground(ABitmapCanvas, ARect,
Rect(0, 0, ABitmap.Width, ABitmap.Height));
inherited InternalPaint(ABitmapCanvas);
ACanvas.Draw(0, 0, ABitmap);
finally
ABitmapCanvas.Free;
ABitmap.Free;
end;
end
else
inherited InternalPaint(ACanvas);
end;
{ TcxCheckGroupButtonProperties }
function TcxCheckGroupButtonProperties.InternalGetGlyph: TBitmap;
begin
Result :=
(TcxCheckGroupButton(Owner).Owner as TcxCustomCheckGroup).ActiveProperties.Glyph;
end;
function TcxCheckGroupButtonProperties.IsEmbeddedEdit: Boolean;
begin
Result := True;
end;
class function TcxCheckGroupButtonProperties.GetViewInfoClass: TcxContainerViewInfoClass;
begin
Result := TcxCheckGroupCheckButtonViewInfo;
end;
{ TcxCheckGroupButton }
destructor TcxCheckGroupButton.Destroy;
begin
TcxCustomCheckGroup(GetOwner).InternalButtons.Remove(Self);
inherited Destroy;
end;
function TcxCheckGroupButton.ExecuteAction(Action: TBasicAction): Boolean;
begin
Result := inherited ExecuteAction(Action) or
CheckGroup.DataBinding.ExecuteAction(Action);
end;
class function TcxCheckGroupButton.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxCheckGroupButtonProperties;
end;
function TcxCheckGroupButton.UpdateAction(Action: TBasicAction): Boolean;
begin
Result := inherited UpdateAction(Action) or
CheckGroup.DataBinding.UpdateAction(Action);
end;
function TcxCheckGroupButton.CanAutoSize: Boolean;
begin
Result := False;
end;
procedure TcxCheckGroupButton.DoExit;
begin
inherited DoExit;
CheckGroup.FFocusedItemIndex := CheckGroup.InternalButtons.IndexOf(Self);
end;
procedure TcxCheckGroupButton.Initialize;
begin
inherited Initialize;
CheckGroup.InternalButtons.Add(Self);
Style.LookAndFeel.MasterLookAndFeel := CheckGroup.LookAndFeel;
Keys := Keys + [kArrows];
CheckTransparentBorder;
end;
function TcxCheckGroupButton.IsNativeBackground: Boolean;
begin
Result := CheckGroup.IsNativeBackground;
end;
function TcxCheckGroupButton.IsNativeStyle: Boolean;
begin
Result := CheckGroup.IsButtonNativeStyle;
end;
function TcxCheckGroupButton.IsTransparent: Boolean;
begin
Result := CheckGroup.IsTransparent;
end;
procedure TcxCheckGroupButton.KeyDown(var Key: Word; Shift: TShiftState);
procedure FocusNearestItem(ADown: Boolean);
var
AIndex, I, ADelta: Integer;
begin
with CheckGroup do
begin
AIndex := InternalButtons.IndexOf(Self);
ADelta := Integer(ADown) - Integer(not ADown);
I := AIndex;
repeat
I := I + ADelta;
if I = InternalButtons.Count then
I := 0
else
if I < 0 then
I := InternalButtons.Count - 1;
if Buttons[I].Enabled then
Break;
until I = AIndex;
if I <> AIndex then
Buttons[I].SetFocus;
end;
end;
var
APrevKeyDownEvent: TKeyEvent;
begin
_TcxContainerAccess.KeyDown(CheckGroup, Key, Shift);
if Key = 0 then
Exit;
if not CheckGroup.IsInplace then
if Key in [VK_UP, VK_LEFT] then
FocusNearestItem(False)
else
if Key in [VK_DOWN, VK_RIGHT] then
FocusNearestItem(True);
APrevKeyDownEvent := OnKeyDown;
OnKeyDown := nil;
inherited KeyDown(Key, Shift);
OnKeyDown := APrevKeyDownEvent;
end;
procedure TcxCheckGroupButton.LookAndFeelChanged(Sender: TcxLookAndFeel;
AChangedValues: TcxLookAndFeelValues);
begin
inherited LookAndFeelChanged(Sender, AChangedValues);
CheckTransparentBorder;
end;
procedure TcxCheckGroupButton.WndProc(var Message: TMessage);
begin
with Message do
if ((Msg = WM_LBUTTONDOWN) or (Msg = WM_LBUTTONDBLCLK)) and
(CheckGroup.DragMode = dmAutomatic) and not(csDesigning in CheckGroup.ComponentState) then
begin
_TcxContainerAccess.BeginAutoDrag(CheckGroup);
Exit;
end;
inherited WndProc(Message);
end;
function TcxCheckGroupButton.GetControl: TWinControl;
begin
Result := Self;
end;
function TcxCheckGroupButton.GetControlContainer: TcxContainer;
begin
Result := CheckGroup;
end;
procedure TcxCheckGroupButton.CheckTransparentBorder;
begin
if Style.LookAndFeel.SkinPainter <> nil then
ViewInfo.Transparent := True;
if not CheckGroup.IsInplace then
Style.TransparentBorder := IsNativeStyle;
end;
function TcxCheckGroupButton.GetCheckGroup: TcxCustomCheckGroup;
begin
Result := TcxCustomCheckGroup(Owner);
end;
{ TcxCustomCheckGroup }
procedure TcxCustomCheckGroup.Activate(var AEditData: TcxCustomEditData);
begin
FFocusedItemIndex := 0;
inherited Activate(AEditData);
end;
class function TcxCustomCheckGroup.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxCustomCheckGroupProperties;
end;
procedure TcxCustomCheckGroup.GetTabOrderList(List: TList);
var
AFocusedItemIndex: Integer;
begin
inherited GetTabOrderList(List);
List.Remove(Self);
if Focused then
AFocusedItemIndex := GetFocusedButtonIndex
else
AFocusedItemIndex := GetFirstEnabledItemIndex(FFocusedItemIndex);
if (AFocusedItemIndex <> -1) and TabStop then
List.Add(InternalButtons[AFocusedItemIndex]);
end;
procedure TcxCustomCheckGroup.SetFocus;
begin
inherited SetFocus;
FFocusedItemIndex := GetFirstEnabledItemIndex(FFocusedItemIndex);
if FFocusedItemIndex <> -1 then
TWinControl(InternalButtons[FFocusedItemIndex]).SetFocus;
end;
procedure TcxCustomCheckGroup.ArrangeButtons;
var
AButtonViewInfo: TcxGroupBoxButtonViewInfo;
I: Integer;
begin
inherited ArrangeButtons;
for I := 0 to InternalButtons.Count - 1 do
with Buttons[I] do
begin
AButtonViewInfo := TcxGroupBoxButtonViewInfo(Self.ViewInfo.ButtonsInfo[I]);
FColumn := AButtonViewInfo.Column;
FRow := AButtonViewInfo.Row;
end;
end;
function TcxCustomCheckGroup.GetButtonDC(AButtonIndex: Integer): THandle;
begin
Result := Buttons[AButtonIndex].Canvas.Handle;
end;
function TcxCustomCheckGroup.GetButtonInstance: TWinControl;
begin
Result := TcxCheckGroupButton.Create(Self, IsInplace);
end;
procedure TcxCustomCheckGroup.Initialize;
begin
inherited Initialize;
ControlStyle := ControlStyle - [csAcceptsControls];
FFocusedItemIndex := -1;
InternalEditValue := 0;
end;
procedure TcxCustomCheckGroup.InternalSetEditValue(const Value: TcxEditValue; AValidateEditValue: Boolean);
begin
inherited InternalSetEditValue(Value, AValidateEditValue);
SynchronizeModifiedAfterEnter;
end;
procedure TcxCustomCheckGroup.InternalValidateDisplayValue(const ADisplayValue: TcxEditValue);
var
APrevEditValue: TcxEditValue;
I: Integer;
begin
APrevEditValue := FEditValue;
SetLength(CheckStates, InternalButtons.Count);
for I := 0 to High(CheckStates) do
CheckStates[I] := Buttons[I].State;
with ActiveProperties do
CalculateEditValueByCheckStates(GetStandaloneEventSender(Self), FEditValue);
if not InternalVarEqualsExact(APrevEditValue, FEditValue) then
DoEditValueChanged;
end;
function TcxCustomCheckGroup.IsEditValueStored: Boolean;
begin
Result := (ActiveProperties.EditValueFormat = cvfInteger) and (EditValue <> 0) or
(ActiveProperties.EditValueFormat <> cvfInteger) and (VarToStr(EditValue) <> '');
end;
procedure TcxCustomCheckGroup.ParentBackgroundChanged;
var
I: Integer;
begin
for I := 0 to InternalButtons.Count - 1 do
Buttons[I].ParentBackground := ParentBackground;
end;
procedure TcxCustomCheckGroup.PropertiesChanged(Sender: TObject);
begin
inherited PropertiesChanged(Sender);
InternalValidateDisplayValue(Null);
DataBinding.UpdateDisplayValue;
end;
procedure TcxCustomCheckGroup.SynchronizeButtonsStyle;
var
AButton: TcxCheckGroupButton;
ADisabledTextColor: TColor;
I: Integer;
begin
inherited SynchronizeButtonsStyle;
ADisabledTextColor := LookAndFeelPainter.DefaultEditorTextColor(True);
if ADisabledTextColor = clDefault then
ADisabledTextColor := StyleDisabled.GetVisibleFont.Color;
for I := 0 to InternalButtons.Count - 1 do
begin
AButton := Buttons[I];
AButton.Style.BorderStyle := ActiveStyle.BorderStyle;
if not AButton.Enabled then
begin
AButton.StyleDisabled.Color := ActiveStyle.Color;
AButton.StyleDisabled.TextColor := ADisabledTextColor;
end;
AButton.Transparent := Transparent; // to repaint button
end;
end;
procedure TcxCustomCheckGroup.SynchronizeDisplayValue;
var
I: Integer;
begin
if ActiveProperties.Items.ItemChanged then
Exit;
with ActiveProperties do
CalculateCheckStatesByEditValue(GetStandaloneEventSender(Self), EditValue);
if not ActiveProperties.AllowGrayed and Focused then
for I := 0 to High(CheckStates) do
if CheckStates[I] = cbsGrayed then
CheckStates[I] := cbsUnchecked;
FButtonStatesChanging := True;
try
for I := 0 to InternalButtons.Count - 1 do
Buttons[I].State := CheckStates[I];
finally
FButtonStatesChanging := False;
end;
end;
procedure TcxCustomCheckGroup.SynchronizeModifiedAfterEnter;
function NeedSynchronize: Boolean;
begin
Result := not ModifiedAfterEnter or ActiveProperties.ImmediatePost;
end;
var
I: Integer;
begin
if NeedSynchronize then
for I := 0 to InternalButtons.Count - 1 do
Buttons[I].ModifiedAfterEnter := False;
end;
procedure TcxCustomCheckGroup.UpdateButtons;
const
ALookAndFeelKindMap: array [TcxEditButtonStyle] of TcxLookAndFeelKind =
(lfStandard, lfStandard, lfFlat, lfStandard, lfStandard,
lfUltraFlat, lfOffice11);
var
AButton: TcxCheckGroupButton;
I: Integer;
begin
inherited UpdateButtons;
if FFocusedItemIndex >= InternalButtons.Count then
FFocusedItemIndex := -1;
for I := 0 to InternalButtons.Count - 1 do
begin
AButton := Buttons[I];
AButton.Properties.BeginUpdate;
try
AButton.Properties.Alignment := ActiveProperties.ItemAlignment;
AButton.Properties.AllowGrayed := ActiveProperties.AllowGrayed;
AButton.Caption := ActiveProperties.Items[I].Caption;
AButton.Properties.MultiLine := ActiveProperties.WordWrap;
AButton.Properties.GlyphCount := ActiveProperties.GlyphCount;
AButton.Properties.ReadOnly := ActiveProperties.ReadOnly and
DataBinding.IsDataAvailable;
if Length(ViewInfo.ButtonsInfo) > 0 then
AButton.LookAndFeel.Kind := ALookAndFeelKindMap[ViewInfo.ButtonsInfo[0].Data.Style];
finally
AButton.Properties.EndUpdate;
AButton.OnEditing := DoButtonEditing;
AButton.OnFocusChanged := DoButtonFocusChanged;
AButton.Properties.OnChange := DoButtonChange;
end;
end;
// SynchronizeDisplayValue;
end;
function TcxCustomCheckGroup.WantNavigationKeys: Boolean;
begin
Result := not IsInplace;
end;
function TcxCustomCheckGroup.GetFirstEnabledItemIndex(AStartIndex: Integer): Integer;
var
I: Integer;
begin
Result := -1;
if AStartIndex = -1 then
AStartIndex := 0;
for I := 0 to InternalButtons.Count - 1 do
if TWinControl(InternalButtons[(I + AStartIndex) mod InternalButtons.Count]).CanFocus then
begin
Result := (I + AStartIndex) mod InternalButtons.Count;
Break;
end;
end;
procedure TcxCustomCheckGroup.DoButtonChange(Sender: TObject);
begin
if FButtonStatesChanging then
Exit;
LockChangeEvents(True);
try
InternalValidateDisplayValue(Null);
ChangeHandler(Self);
if ActiveProperties.ImmediatePost and CanPostEditValue and ValidateEdit(True) then
begin
InternalPostEditValue;
SynchronizeModifiedAfterEnter;
end;
finally
LockChangeEvents(False);
end;
end;
procedure TcxCustomCheckGroup.DoButtonEditing(Sender: TObject; var CanEdit: Boolean);
begin
CanEdit := DoEditing;
end;
procedure TcxCustomCheckGroup.DoButtonFocusChanged(Sender: TObject);
begin
FocusChanged;
end;
function TcxCustomCheckGroup.GetActiveProperties: TcxCustomCheckGroupProperties;
begin
Result := TcxCustomCheckGroupProperties(InternalGetActiveProperties);
end;
function TcxCustomCheckGroup.GetButton(Index: Integer): TcxCheckGroupButton;
begin
Result := TcxCheckGroupButton(InternalButtons[Index]);
end;
function TcxCustomCheckGroup.GetProperties: TcxCustomCheckGroupProperties;
begin
Result := TcxCustomCheckGroupProperties(FProperties);
end;
function TcxCustomCheckGroup.GetState(Index: Integer): TcxCheckBoxState;
begin
Result := Buttons[Index].State;
end;
procedure TcxCustomCheckGroup.SetProperties(Value: TcxCustomCheckGroupProperties);
begin
FProperties.Assign(Value);
end;
procedure TcxCustomCheckGroup.SetState(Index: Integer; Value: TcxCheckBoxState);
begin
Buttons[Index].State := Value;
end;
{ TcxCheckGroup }
class function TcxCheckGroup.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxCheckGroupProperties;
end;
function TcxCheckGroup.GetActiveProperties: TcxCheckGroupProperties;
begin
Result := TcxCheckGroupProperties(InternalGetActiveProperties);
end;
function TcxCheckGroup.GetProperties: TcxCheckGroupProperties;
begin
Result := TcxCheckGroupProperties(FProperties);
end;
procedure TcxCheckGroup.SetProperties(Value: TcxCheckGroupProperties);
begin
FProperties.Assign(Value);
end;
{ TcxFilterCheckGroupHelper }
class function TcxFilterCheckGroupHelper.GetEditValueFormat(
AEditProperties: TcxCustomEditProperties): TcxCheckStatesValueFormat;
begin
Result := TcxCustomCheckGroupProperties(AEditProperties).EditValueFormat;
end;
class function TcxFilterCheckGroupHelper.GetItems(
AEditProperties: TcxCustomEditProperties): IcxCheckItems;
begin
Result := TcxCustomCheckGroupProperties(AEditProperties).Items;
end;
class procedure TcxFilterCheckGroupHelper.InitializeItems(AProperties,
AEditProperties: TcxCustomEditProperties);
begin
inherited InitializeItems(AProperties, AEditProperties);
TcxCustomCheckComboBoxProperties(AProperties).Glyph :=
TcxCustomCheckGroupProperties(AEditProperties).Glyph;
TcxCustomCheckComboBoxProperties(AProperties).GlyphCount :=
TcxCustomCheckGroupProperties(AEditProperties).GlyphCount;
end;
initialization
GetRegisteredEditProperties.Register(TcxCheckGroupProperties,
scxSEditRepositoryCheckGroupItem);
FilterEditsController.Register(TcxCheckGroupProperties,
TcxFilterCheckGroupHelper);
finalization
FilterEditsController.Unregister(TcxCheckGroupProperties,
TcxFilterCheckGroupHelper);
GetRegisteredEditProperties.Unregister(TcxCheckGroupProperties);
end.