Componentes.Terceros.DevExp.../official/x.36/ExpressEditors Library 5/Sources/cxLabel.pas
2008-06-02 17:37:37 +00:00

1364 lines
43 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 cxLabel;
{$I cxVer.inc}
interface
uses
{$IFDEF DELPHI6}
Types, Variants,
{$ENDIF}
Windows, Classes, Controls, Forms, Graphics, Messages, SysUtils, cxClasses,
cxContainer, cxControls, cxCustomData, cxDataUtils, cxEdit, cxExtEditConsts,
cxGraphics, cxTextEdit, cxVariants;
type
TcxLabelEffect = (cxleNormal, cxleFun, cxleExtrude, cxleCool);
TcxLabelStyle = (cxlsNormal, cxlsRaised, cxlsLowered, cxlsOutLine);
TcxLabelOrientation = (cxoLeft, cxoRight, cxoTop, cxoBottom, cxoLeftTop,
cxoLeftBottom, cxoRightTop, cxoRightBottom);
{ TcxLabelEditStyle }
TcxLabelEditStyle = class(TcxEditStyle)
protected
function DefaultBorderStyle: TcxContainerBorderStyle; override;
function DefaultHotTrack: Boolean; override;
end;
{ TcxCustomLabelViewInfo }
TcxCustomLabelViewInfo = class(TcxCustomTextEditViewInfo)
private
FAlignment: TcxEditAlignment;
FAngle: Integer;
FDepth: Word;
FDepthDeltaSize: TSize;
FDrawBitmap: TBitmap;
FGlyph: TBitmap;
FIsDrawBitmapDirty: Boolean;
FInplaceOffset: TPoint;
FLabelEffect: TcxLabelEffect;
FLabelStyle: TcxLabelStyle;
FLabelTextRect: TRect;
FOrientation: TcxLabelOrientation;
FPenWidth: Integer;
FShadowedColor: TColor;
FWordWrap: Boolean;
protected
procedure SetBackgroundColor(Value: TColor); override;
property Alignment: TcxEditAlignment read FAlignment write FAlignment;
property LabelEffect: TcxLabelEffect read FLabelEffect write FLabelEffect;
property LabelStyle: TcxLabelStyle read FLabelStyle write FLabelStyle;
property Orientation: TcxLabelOrientation read FOrientation write FOrientation;
property Depth: Word read FDepth write FDepth;
property DepthDeltaSize: TSize read FDepthDeltaSize write FDepthDeltaSize;
property ShadowedColor: TColor read FShadowedColor write FShadowedColor;
property Angle: Integer read FAngle write FAngle;
property PenWidth: Integer read FPenWidth write FPenWidth;
property WordWrap: Boolean read FWordWrap write FWordWrap;
property Glyph: TBitmap read FGlyph write FGlyph;
property LabelTextRect: TRect read FLabelTextRect write FLabelTextRect;
public
DrawTextOffsets: TRect;
FocusRect: TRect;
HasGlyph: Boolean;
LeftTop: TPoint;
ShowAccelChar: Boolean;
constructor Create; override;
destructor Destroy; override;
procedure Offset(DX, DY: Integer); override;
procedure Paint(ACanvas: TcxCanvas); override;
procedure DrawLabel(ACanvas: TcxCanvas); virtual;
end;
{ TcxCustomLabelViewData }
TcxCustomLabelProperties = class;
TcxCustomLabelViewData = class(TcxCustomEditViewData)
private
function GetProperties: TcxCustomLabelProperties;
procedure CalculateLabelViewInfoProps(AViewInfo: TcxCustomEditViewInfo);
protected
function GetDrawTextFlags: Integer; virtual;
function GetIsEditClass: Boolean;
function InternalEditValueToDisplayText(AEditValue: TcxEditValue): string; 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;
function GetEditContentSize(ACanvas: TcxCanvas; const AEditValue: TcxEditValue;
const AEditSizeProperties: TcxEditSizeProperties): TSize; override;
property Properties: TcxCustomLabelProperties read GetProperties;
end;
{ TcxCustomLabelProperties }
TcxCustomLabelProperties = class(TcxCustomEditProperties)
private
FLabelEffect: TcxLabelEffect;
FLabelStyle: TcxLabelStyle;
FOrientation: TcxLabelOrientation;
FDepth: Word;
FShadowedColor: TColor;
FShowAccelChar: Boolean;
FShowEndEllipsis: Boolean; // deprecated
FAngle: Integer;
FPenWidth: Integer;
FGlyph: TBitmap;
FWordWrap: Boolean;
procedure SetLabelEffect(Value : TcxLabelEffect);
procedure SetLabelStyle(Value : TcxLabelStyle);
procedure SetOrientation(Value : TcxLabelOrientation);
procedure SetDepth(Value : Word);
procedure SetShadowedColor(Value : TColor);
procedure SetAngle(Value: Integer);
procedure SetPenWidth(Value: Integer);
function GetGlyph: TBitmap;
procedure GlyphChanged(Sender: TObject);
procedure SetGlyph(Value: TBitmap);
procedure SetShowAccelChar(Value: Boolean);
procedure SetWordWrap(Value: Boolean);
protected
class function GetViewDataClass: TcxCustomEditViewDataClass; override;
function HasDisplayValue: Boolean; override;
function CalculateDepthDelta: TSize; virtual;
function GetDisplayFormatOptions: TcxEditDisplayFormatOptions; override;
property ShowEndEllipsis: Boolean read FShowEndEllipsis
write FShowEndEllipsis stored False; // deprecated
public
constructor Create(AOwner: TPersistent); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
function CanCompareEditValue: Boolean; override;
class function GetContainerClass: TcxContainerClass; override;
class function GetStyleClass: TcxCustomEditStyleClass; override;
function GetDisplayText(const AEditValue: TcxEditValue;
AFullText: Boolean = False; AIsInplace: Boolean = True): WideString; override;
function GetSupportedOperations: TcxEditSupportedOperations; override;
class function GetViewInfoClass: TcxContainerViewInfoClass; override;
function IsEditValueValid(var EditValue: TcxEditValue; AEditFocused: Boolean): Boolean; override;
procedure PrepareDisplayValue(const AEditValue: TcxEditValue;
var DisplayValue: TcxEditValue; AEditFocused: Boolean); override;
function GetEditValueSource(AEditFocused: Boolean): TcxDataEditValueSource; override;
// !!!
property Angle: Integer read FAngle write SetAngle default 0;
property Depth: Word read FDepth write SetDepth default 0;
property Glyph: TBitmap read GetGlyph write SetGlyph;
property LabelEffect: TcxLabelEffect read FLabelEffect
write SetLabelEffect default cxleNormal;
property LabelStyle: TcxLabelStyle read FLabelStyle
write SetLabelStyle default cxlsNormal;
property Orientation: TcxLabelOrientation read FOrientation
write SetOrientation default cxoRightBottom;
property PenWidth: Integer read FPenWidth write SetPenWidth default 1;
property ShadowedColor: TColor read FShadowedColor
write SetShadowedColor default clGrayText;
property ShowAccelChar: Boolean read FShowAccelChar write SetShowAccelChar
default True;
property Transparent; // deprecated
property WordWrap: Boolean read FWordWrap write SetWordWrap default False;
end;
{ TcxLabelProperties }
TcxLabelProperties = class(TcxCustomLabelProperties)
published
property Alignment;
property Angle;
property Depth;
property Glyph;
property LabelEffect;
property LabelStyle;
property Orientation;
property PenWidth;
property ShadowedColor;
property ShowAccelChar;
property ShowEndEllipsis; // deprecated
property Transparent; // deprecated
property WordWrap;
end;
{ TcxCustomLabel }
TcxCustomLabel = class(TcxCustomEdit)
private
FFocusControl: TWinControl;
FLockCaption: Boolean;
function GetProperties: TcxCustomLabelProperties;
function GetActiveProperties: TcxCustomLabelProperties;
function GetStyle: TcxLabelEditStyle;
function GetViewInfo: TcxCustomLabelViewInfo;
procedure SetProperties(Value: TcxCustomLabelProperties);
procedure SetStyle(Value: TcxLabelEditStyle);
procedure SetFocusControl(Value: TWinControl);
procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
protected
procedure Initialize; override;
procedure InternalSetEditValue(const Value: TcxEditValue; AValidateEditValue: Boolean); override;
function IsRightBoundFixed: Boolean; override;
procedure Loaded; override;
procedure SetInternalDisplayValue(Value: TcxEditValue); override;
procedure TextChanged; override;
function CanAutoWidth: Boolean; override;
function CanFocusOnClick: Boolean; override;
function DefaultParentColor: Boolean; override;
procedure Notification(ACOmponent: TComponent; Operation: TOperation); override;
property FocusControl: TWinControl read FFocusControl write SetFocusControl;
property ViewInfo: TcxCustomLabelViewInfo read GetViewInfo;
public
destructor Destroy; override;
class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
function CanFocus: Boolean; override;
{$IFDEF DELPHI10}
function GetTextBaseLine: Integer; override;
function HasTextBaseLine: Boolean; override;
{$ENDIF}
property ActiveProperties: TcxCustomLabelProperties
read GetActiveProperties;
property Caption;
property Properties: TcxCustomLabelProperties read GetProperties
write SetProperties;
property Style: TcxLabelEditStyle read GetStyle write SetStyle;
property TabOrder stored False;
property Transparent;
end;
{ TcxCustomLabel }
TcxLabel = class(TcxCustomLabel)
private
function GetActiveProperties: TcxLabelProperties;
function GetProperties: TcxLabelProperties;
procedure SetProperties(Value: TcxLabelProperties);
public
class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
property ActiveProperties: TcxLabelProperties read GetActiveProperties;
published
property Align;
property Anchors;
property AutoSize;
property Caption;
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property FocusControl;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property Properties: TcxLabelProperties read GetProperties
write SetProperties;
property ShowHint;
property Style;
property StyleDisabled;
property StyleFocused;
property StyleHot;
property TabOrder;
property Transparent;
property Visible;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseEnter;
property OnMouseLeave;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
end;
implementation
uses
Math, cxEditConsts, cxEditPaintUtils, cxEditUtils, cxExtEditUtils,
cxFilterControlUtils, dxThemeConsts, dxThemeManager, dxUxTheme;
const
TextFromBorderOffset = 1;
procedure CalculateCustomLabelViewInfo(ACanvas: TcxCanvas; AViewData: TcxCustomLabelViewData;
AViewInfo: TcxCustomLabelViewInfo);
procedure CheckFocusRectBounds;
begin
with AViewInfo do
begin
if FocusRect.Left < TextRect.Left - 1 then
FocusRect.Left := TextRect.Left - 1;
if FocusRect.Top < TextRect.Top - 1 then
FocusRect.Top := TextRect.Top - 1;
if FocusRect.Right > TextRect.Right + 1 then
FocusRect.Right := TextRect.Right + 1;
if FocusRect.Bottom > TextRect.Bottom + 1 then
FocusRect.Bottom := TextRect.Bottom + 1;
end;
end;
begin
with AViewInfo do
begin
if not IsInplace and Focused then
if Length(Text) = 0 then
FocusRect := cxEmptyRect
else
begin
FocusRect := TextRect;
InflateRect(FocusRect, 1, 1);
CheckFocusRectBounds;
end;
end;
end;
{ TcxLabelEditStyle }
function TcxLabelEditStyle.DefaultBorderStyle: TcxContainerBorderStyle;
begin
if IsBaseStyle then
Result := cbsNone
else
Result := inherited DefaultBorderStyle;
end;
function TcxLabelEditStyle.DefaultHotTrack: Boolean;
begin
Result := False;
end;
{ TcxCustomLabelViewInfo }
constructor TcxCustomLabelViewInfo.Create;
begin
inherited Create;
FAlignment := TcxEditAlignment.Create(nil);
FDrawBitmap := TBitmap.Create;
FInplaceOffset := Point(MaxInt, MaxInt);
end;
destructor TcxCustomLabelViewInfo.Destroy;
begin
FreeAndNil(FDrawBitmap);
if Assigned(FAlignment) then FreeAndNil(FAlignment);
inherited;
end;
procedure TcxCustomLabelViewInfo.Offset(DX, DY: Integer);
begin
inherited Offset(DX, DY);
OffsetRect(FLabelTextRect, DX, DY);
OffsetRect(FocusRect, DX, DY);
if Transparent then
FIsDrawBitmapDirty := True;
end;
procedure TcxCustomLabelViewInfo.Paint(ACanvas: TcxCanvas);
begin
DrawCustomEdit(ACanvas, Self, False, bpsSolid);
DrawLabel(ACanvas);
end;
procedure TcxCustomLabelViewInfo.DrawLabel(ACanvas: TcxCanvas);
function GetColor(BColor, EColor: TColor; N,H: Integer) : TColor;
begin
EColor := ColorToRGB(EColor);
BColor := ColorToRGB(BColor);
Result := RGB(Trunc(GetRValue(BColor) + (GetRValue(EColor) - GetRValue(BColor)) * N / H),
Trunc(GetGValue(BColor) + (GetGValue(EColor) - GetGValue(BColor)) * N / H),
Trunc(GetBValue(BColor) + (GetBValue(EColor) - GetBValue(BColor)) * N / H));
end;
procedure DrawBackground(ADrawCanvas: TcxCanvas; const ADrawingRect: TRect;
AParentBackgroundOffset: TPoint);
begin
if Self.DrawBackground(ADrawCanvas, AParentBackgroundOffset) then
Exit;
if not Transparent or IsInplace and Focused then
cxEditFillRect(ADrawCanvas, ADrawingRect, BackgroundColor)
else
if IsInplace then
BitBlt(ADrawCanvas.Handle, ADrawingRect.Left, ADrawingRect.Top,
RectWidth(ADrawingRect), RectHeight(ADrawingRect), ACanvas.Handle,
AParentBackgroundOffset.X, AParentBackgroundOffset.Y, SRCCOPY)
else
begin
if not (csPaintCopy in Edit.ControlState) then
begin
with AParentBackgroundOffset do
cxDrawTransparentControlBackground(Edit, ADrawCanvas,
Rect(X, Y, X + RectWidth(ADrawingRect), Y + RectHeight(ADrawingRect)));
end;
end;
end;
function GetLabelStyleOffset: Integer;
begin
Result := 0;
if LabelStyle in [cxlsRaised, cxlsLowered] then
begin
if Font.Size >= 12 then
Result := 2
else
Result := 1;
end;
end;
function GetTextDrawingParameters(ACanvas: TCanvas; ADrawingRect: TRect;
AAngle: Integer; out AStep: TSize): TPoint;
procedure CalcRotatedTextPos(ACanvas: TCanvas);
var
ARect: TRect;
AText: string;
begin
if AAngle <> 0 then
begin
ARect := ADrawingRect;
Dec(ARect.Right, DepthDeltaSize.cx);
Dec(ARect.Bottom, DepthDeltaSize.cy);
AText := Text;
if ShowAccelChar then
AText := RemoveAccelChars(AText);
cxDrawText(ACanvas.Handle, AText, ADrawingRect, DT_CALCRECT or DT_NOPREFIX);
Result.X := Round(
(ARect.Left + ARect.Right)/2 -
RectWidth(ADrawingRect) / 2 * Cos(AAngle * PI / 180) -
RectHeight(ADrawingRect) / 2 * Sin(AAngle * PI / 180));
Result.Y := Round(
(ARect.Top + ARect.Bottom)/2 +
RectWidth(ADrawingRect) / 2 * Sin(AAngle * PI / 180) -
RectHeight(ADrawingRect) / 2 * Cos(AAngle * PI / 180));
end;
end;
function GetSignByValue(AValue: Longint): ShortInt;
begin
Result := 0;
if AValue = 0 then
Exit;
if AValue > 0 then
Result := 1
else
Result := -1;
end;
var
ALabelStyleOffset: Integer;
begin
Result := Point(0, 0);
CalcRotatedTextPos(ACanvas);
AStep := Size(0, 0);
ALabelStyleOffset := GetLabelStyleOffset;
if (LabelEffect <> cxleNormal) and (FDepth <> 0) then
begin
AStep := DepthDeltaSize;
if Orientation in [cxoRight, cxoRightTop, cxoRightBottom] then
begin
Inc(Result.X, DepthDeltaSize.cx + ALabelStyleOffset);
AStep.cx := -AStep.cx;
end;
if Orientation in [cxoBottom, cxoLeftBottom , cxoRightBottom] then
begin
Inc(Result.Y, DepthDeltaSize.cy + ALabelStyleOffset);
AStep.cy := -AStep.cy;
end;
if LabelEffect in [cxleFun, cxleExtrude] then
begin
AStep.cx := GetSignByValue(AStep.cx);
AStep.cy := GetSignByValue(AStep.cy);
end;
end;
end;
procedure DrawActualText(ACanvas: TcxCanvas; const ADrawingRect: TRect;
const APosition: TPoint; AIsTextRotated: Boolean);
var
ATextRect: TRect;
AText: string;
begin
ATextRect := ADrawingRect;
if not AIsTextRotated then
begin
Dec(ATextRect.Right, DepthDeltaSize.cx);
Dec(ATextRect.Bottom, DepthDeltaSize.cy);
OffsetRect(ATextRect, APosition.X, APosition.Y);
ACanvas.DrawText(Text, ATextRect,
PrepareTextFlag(0, Alignment.Horz, TcxAlignmentVert(Ord(Alignment.Vert)),
(epoShowEndEllipsis in PaintOptions) and IsInplace,
WordWrap, 0, False, ShowAccelChar));
end
else
begin
AText := Text;
if ShowAccelChar then
AText := RemoveAccelChars(AText);
ExtTextOut(ACanvas.Handle, APosition.X, APosition.Y, 0,
@ATextRect, PChar(AText),
Length(AText), nil);
end;
end;
procedure DrawLabelEffect(ACanvas: TcxCanvas; const ADrawingRect: TRect;
var AStartPos: TPoint; const AStep: TSize; AIsTextRotated: Boolean);
var
AIterationCount, I: Integer;
begin
if (LabelEffect = cxleNormal) or (FDepth = 0) then
Exit;
if AStep.cx <> 0 then
AIterationCount := FDepth div Abs(AStep.cx)
else
AIterationCount := FDepth div Abs(AStep.cy);
if LabelEffect <> cxleFun then
ACanvas.Font.Color := ShadowedColor;
for I := 1 to AIterationCount do
begin
if LabelEffect = cxleFun then
ACanvas.Font.Color :=
GetColor(BackgroundColor, ShadowedColor, I, AIterationCount);
DrawActualText(ACanvas, ADrawingRect, AStartPos, AIsTextRotated);
Inc(AStartPos.X, AStep.cx);
Inc(AStartPos.Y, AStep.cy);
end;
end;
procedure DrawConventionalizedText(ACanvas: TcxCanvas; ARect: TRect;
const APosition: TPoint; AGlyph: TBitmap; AIsTrueType: Boolean;
AIsTextRotated: Boolean);
procedure DrawFilledText(XPosOffset, YPosOffset: Integer;
AGlyphOnly: Boolean = False);
begin
if not AGlyph.Empty and AIsTrueType and (AGlyph.Width > 0) and
(AGlyph.Height > 0) then
begin
BeginPath(ACanvas.Handle);
DrawActualText(ACanvas, ARect, Point(APosition.X + XPosOffset,
APosition.Y + YPosOffset), AIsTextRotated);
EndPath(ACanvas.Handle);
SelectClipPath(ACanvas.Handle, RGN_COPY);
ACanvas.FillRect(ARect, AGlyph);
SelectClipRgn(ACanvas.Handle, 0);
end
else
if not AGlyphOnly then
DrawActualText(ACanvas, ARect, Point(APosition.X + XPosOffset,
APosition.Y + YPosOffset), AIsTextRotated);
end;
begin
ACanvas.Font.Color := TextColor;
case LabelStyle of
cxlsNormal:
DrawFilledText(0, 0);
cxlsRaised:
begin
ACanvas.Font.Color := clBtnHighlight;
DrawActualText(ACanvas, ARect, APosition,
AIsTextRotated);
if Font.Size >= 12 then
begin
ACanvas.Font.Color := clBtnShadow;
DrawActualText(ACanvas, ARect, Point(APosition.X + 2, APosition.Y + 2),
AIsTextRotated);
end;
ACanvas.Font.Color := TextColor;
DrawFilledText(1, 1);
end;
cxlsLowered:
begin
if Font.Size >= 12 then
begin
ACanvas.Font.Color := clBtnShadow;
DrawActualText(ACanvas, ARect, APosition,
AIsTextRotated);
end;
ACanvas.Font.Color := clBtnHighlight;
DrawActualText(ACanvas, ARect, Point(APosition.X + 2, APosition.Y + 2),
AIsTextRotated);
ACanvas.Font.Color := TextColor;
DrawFilledText(1, 1);
end;
cxlsOutLine:
begin
DrawFilledText(0, 0, AIsTrueType);
if AIsTrueType then
begin
BeginPath(ACanvas.Handle);
DrawActualText(ACanvas, ARect, APosition, AIsTextRotated);
EndPath(ACanvas.Handle);
ACanvas.Pen.Color := TextColor;
ACanvas.Pen.Width := FPenWidth;
StrokePath(ACanvas.Handle);
ACanvas.Pen.Width := 1;
end;
end;
end;
end;
procedure AdjustTextPosWithLabelStyle(var APosition: TPoint;
const AStep: TSize);
var
ALabelStyleOffset: Integer;
begin
ALabelStyleOffset := GetLabelStyleOffset;
if AStep.cx < 0 then
Dec(APosition.X, ALabelStyleOffset);
if AStep.cy < 0 then
Dec(APosition.Y, ALabelStyleOffset);
end;
procedure AdjustTextRectWithOffset(var ATextRect: TRect);
begin
if IsInplace then
with DrawTextOffsets do
begin
Inc(ATextRect.Left, Left);
Inc(ATextRect.Top, Top);
Dec(ATextRect.Right, Right);
Dec(ATextRect.Bottom, Bottom);
end
else
if BorderStyle <> ebsNone then
InflateRect(ATextRect, -TextFromBorderOffset, 0);
end;
procedure InternalDrawLabel(ADrawCanvas: TcxCanvas;
const ABackgroundRect, ATextRect: TRect; const AParentBackgroundOffset: TPoint);
var
AIsTrueType: Boolean;
ARealAngle: Integer;
AStep: TSize;
AStartPos: TPoint;
begin
DrawBackground(ADrawCanvas, ABackgroundRect, AParentBackgroundOffset);
AIsTrueType := AdjustCanvasFont(ADrawCanvas.Canvas, Font, FAngle);
ARealAngle := Integer(AIsTrueType) * FAngle;
ARealAngle := (ARealAngle mod 360 + 360) mod 360;
AStartPos := GetTextDrawingParameters(ADrawCanvas.Canvas, ATextRect,
ARealAngle, AStep);
ADrawCanvas.Brush.Style := bsClear;
DrawLabelEffect(ADrawCanvas, ATextRect, AStartPos, AStep, ARealAngle <> 0);
AdjustTextPosWithLabelStyle(AStartPos, AStep);
DrawConventionalizedText(ADrawCanvas, ATextRect, AStartPos, FGlyph,
AIsTrueType, ARealAngle <> 0);
ADrawCanvas.Brush.Style := bsSolid;
end;
function InplaceOffsetChanged: Boolean;
begin
Result := (FInplaceOffset.X <> Left) or (FInplaceOffset.Y <> Top);
if Result then
begin
FInplaceOffset.X := Left;
FInplaceOffset.Y := Top;
end;
end;
var
ABitmapCanvas: TcxCanvas;
AContentRect, ATextRect: TRect;
APrevLogFont: TLogFont;
begin
SaveCanvasFont(ACanvas, APrevLogFont);
try
AContentRect := LabelTextRect;
ATextRect := LabelTextRect;
AdjustTextRectWithOffset(ATextRect);
if not IsInplace and Transparent and (csPaintCopy in Edit.ControlState) then
InternalDrawLabel(ACanvas, AContentRect, ATextRect, AContentRect.TopLeft)
else
begin
if not IsInplace and NativeStyle then
GetThemeBackgroundContentRect(OpenTheme(totEdit), ACanvas.Handle,
EP_EDITTEXT, NativeState, Bounds, AContentRect);
if InplaceOffsetChanged or FIsDrawBitmapDirty or Transparent then
begin
FDrawBitmap.Width := RectWidth(AContentRect);
FDrawBitmap.Height := RectHeight(AContentRect);
ABitmapCanvas := TcxCanvas.Create(FDrawBitmap.Canvas);
OffsetRect(ATextRect, -AContentRect.Left, -AContentRect.Top);
try
InternalDrawLabel(ABitmapCanvas, Rect(0, 0, FDrawBitmap.Width, FDrawBitmap.Height),
ATextRect, AContentRect.TopLeft);
finally
FreeAndNil(ABitmapCanvas);
end;
FIsDrawBitmapDirty := False;
end;
BitBlt(ACanvas.Handle, AContentRect.Left, AContentRect.Top,
FDrawBitmap.Width, FDrawBitmap.Height, FDrawBitmap.Canvas.Handle, 0, 0, SRCCOPY);
end;
finally
RestoreCanvasFont(ACanvas, APrevLogFont);
end;
end;
procedure TcxCustomLabelViewInfo.SetBackgroundColor(Value: TColor);
begin
inherited SetBackgroundColor(Value);
FIsDrawBitmapDirty := True;
end;
{ TcxCustomLabelViewData }
procedure TcxCustomLabelViewData.CalculateLabelViewInfoProps(AViewInfo: TcxCustomEditViewInfo);
begin
with TcxCustomLabelViewInfo(AViewInfo) do
begin
LabelEffect := Properties.LabelEffect;
LabelStyle := Properties.LabelStyle;
Orientation := Properties.Orientation;
Depth := Properties.Depth;
ShadowedColor := Properties.ShadowedColor;
ShowAccelChar := Properties.ShowAccelChar;
Angle := Properties.Angle;
PenWidth := Properties.PenWidth;
WordWrap := Properties.WordWrap;
Alignment.Assign(Properties.Alignment);
Glyph := Properties.Glyph;
end;
end;
procedure TcxCustomLabelViewData.Calculate(ACanvas: TcxCanvas; const ABounds: TRect;
const P: TPoint; Button: TcxMouseButton; Shift: TShiftState; AViewInfo: TcxCustomEditViewInfo;
AIsMouseEvent: Boolean);
var
ALabelViewInfo: TcxCustomLabelViewInfo;
begin
inherited Calculate(ACanvas, ABounds, P, Button, Shift, AViewInfo, AIsMouseEvent);
if ((ABounds.Bottom >= MaxInt) or (ABounds.Right >= MaxInt)) and IsInplace then
Exit;
ALabelViewInfo := TcxCustomLabelViewInfo(AViewInfo);
{Standart properties}
ALabelViewInfo.IsEditClass := GetIsEditClass;
ALabelViewInfo.DrawSelectionBar := False;
ALabelViewInfo.HasPopupWindow := False;
ALabelViewInfo.DrawTextFlags := GetDrawTextFlags;
if AreVisualStylesMustBeUsed(ALabelViewInfo.NativeStyle, totButton) and
(ALabelViewInfo.BorderStyle = ebsNone) then
ALabelViewInfo.NativeStyle := False;
if not IsInplace then
ALabelViewInfo.Transparent := TcxCustomLabel(Edit).Transparent;
{Label properties}
CalculateLabelViewInfoProps(ALabelViewInfo);
ALabelViewInfo.DepthDeltaSize := Properties.CalculateDepthDelta;
ALabelViewInfo.TextRect := AViewInfo.ClientRect;
ALabelViewInfo.LabelTextRect := AViewInfo.ClientRect;
CalculateCustomLabelViewInfo(ACanvas, Self, ALabelViewInfo);
if not IsInplace then ALabelViewInfo.DrawSelectionBar := False;
if Edit <> nil then
ALabelViewInfo.LeftTop := Point(Edit.Left, Edit.Top);
ALabelViewInfo.DrawTextOffsets := GetTextEditDrawTextOffset(Self);
ALabelViewInfo.FIsDrawBitmapDirty := True;
end;
procedure TcxCustomLabelViewData.EditValueToDrawValue(ACanvas: TcxCanvas;
const AEditValue: TcxEditValue; AViewInfo: TcxCustomEditViewInfo);
begin
TcxCustomLabelViewInfo(AViewInfo).Text := EditValueToDisplayText(AEditValue);
end;
function TcxCustomLabelViewData.GetEditContentSize(ACanvas: TcxCanvas;
const AEditValue: TcxEditValue; const AEditSizeProperties: TcxEditSizeProperties): TSize;
function CalculateLabelTextSize(ACanvas: TcxCanvas; const AText: string;
const ATextRect: TRect; AAngle: Integer; ADepthSize,
AContentSizeCorrection: TSize; ALabelStyleOffset: Integer; AIsInplace,
AWordWrap, AShowAccelChar: Boolean): TSize;
var
ARealAngle, ATextFlag, ATextWidth: Integer;
ARealText: string;
ARect: TRect;
ARealWordWrap: Boolean;
begin
ARect := Rect(0, 0, RectWidth(ATextRect), RectHeight(ATextRect));
ARealAngle := (AAngle mod 360 + 360) mod 360;
ARealWordWrap := AWordWrap and (ARealAngle = 0);
if ARect.Right < 0 then
begin
if AIsInplace then
ARealWordWrap := False;
end
else
begin
Dec(ARect.Right, ADepthSize.cx + ALabelStyleOffset);
if (Style.BorderStyle <> ebsNone) and not AIsInplace then
Dec(ARect.Right, TextFromBorderOffset * 2);
if AIsInplace then
Dec(ARect.Right, AContentSizeCorrection.cx);
end;
ATextFlag := PrepareTextFlag(DT_CALCRECT, TAlignment(0),
TcxAlignmentVert(0), False,
ARealWordWrap, 0, True, AShowAccelChar and (ARealAngle = 0));
ARealText := AText;
if (ARealAngle <> 0) and AShowAccelChar then
ARealText := RemoveAccelChars(AText);
cxDrawText(ACanvas.Handle, ARealText, ARect, ATextFlag);
if ARealAngle <> 0 then
begin
ATextWidth := ARect.Right;
ARect.Right := Trunc(Abs(ARect.Right * Cos(ARealAngle * PI / 180)) +
Abs(ARect.Bottom * Sin(ARealAngle * PI / 180)) + 0.5);
ARect.Bottom := Trunc(Abs(ATextWidth * Sin(ARealAngle * PI / 180)) +
Abs(ARect.Bottom * Cos(ARealAngle * PI / 180)) + 0.5);
end;
Result.cx := ARect.Right;
Result.cy := ARect.Bottom;
Result.cx := Result.cx + ADepthSize.cx + ALabelStyleOffset;
Result.cy := Result.cy + ADepthSize.cy + ALabelStyleOffset;
if (Style.BorderStyle <> ebsNone) and not AIsInplace then
Result.cx := Result.cx + TextFromBorderOffset * 2;
if AIsInplace then
begin
Result.cx := Result.cx + AContentSizeCorrection.cx;
Result.cy := Result.cy + AContentSizeCorrection.cy;
end;
end;
var
ADisplayText: string;
ALabelStyleOffset: Integer;
APrevLogFont: TLogFont;
ARealAngle: Integer;
ASizeDelta: TSize;
begin
SaveCanvasFont(ACanvas, APrevLogFont);
try
Result := Size(0, 0);
if Edit <> nil then
ADisplayText := TcxCustomLabel(Edit).ViewInfo.Text
else
ADisplayText := EditValueToDisplayText(AEditValue);
if ADisplayText = '' then
ADisplayText := ' ';
Result.cx := AEditSizeProperties.Width;
ARealAngle := Integer(AdjustCanvasFont(ACanvas.Canvas, Style.GetVisibleFont, Properties.Angle)) *
Properties.Angle;
ASizeDelta := Properties.CalculateDepthDelta;
if Properties.LabelStyle in [cxlsRaised, cxlsLowered] then
begin
if ACanvas.Font.Size >= 12 then
ALabelStyleOffset := 2
else
ALabelStyleOffset := 1;
end
else
ALabelStyleOffset := 0;
with Properties do
Result := CalculateLabelTextSize(ACanvas, ADisplayText,
Rect(0, 0, Result.cx, Result.cy), ARealAngle, ASizeDelta,
Self.GetEditContentSizeCorrection, ALabelStyleOffset, IsInplace,
WordWrap, Properties.ShowAccelChar);
finally
RestoreCanvasFont(ACanvas, APrevLogFont);
end;
end;
function TcxCustomLabelViewData.GetDrawTextFlags: Integer;
var
ARealAngle: Integer;
begin
ARealAngle := (Properties.Angle mod 360 + 360) mod 360;
Result := DrawTextFlagsTocxTextOutFlags(
PrepareTextFlag(0, Properties.Alignment.Horz,
TcxAlignmentVert(Ord(Properties.Alignment.Vert)),
epoShowEndEllipsis in PaintOptions,
Properties.WordWrap and (ARealAngle = 0), 0, False));
end;
function TcxCustomLabelViewData.GetIsEditClass: Boolean;
begin
Result := False;
end;
function TcxCustomLabelViewData.InternalEditValueToDisplayText(
AEditValue: TcxEditValue): string;
begin
Result := VarToStr(AEditValue);
end;
function TcxCustomLabelViewData.GetProperties: TcxCustomLabelProperties;
begin
Result := TcxCustomLabelProperties(FProperties);
end;
{ TcxCustomLabelProperties }
constructor TcxCustomLabelProperties.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FLabelEffect := cxleNormal;
FLabelStyle := cxlsNormal;
FOrientation := cxoRightBottom;
FDepth := 0;
FShadowedColor := clGrayText;
FShowAccelChar := True;
FAngle := 0;
FPenWidth := 1;
FWordWrap := False;
end;
destructor TcxCustomLabelProperties.Destroy;
begin
if FGlyph <> nil then FreeAndNil(FGlyph);
inherited Destroy;
end;
procedure TcxCustomLabelProperties.Assign(Source: TPersistent);
begin
if Source is TcxCustomLabelProperties then
begin
BeginUpdate;
try
inherited Assign(Source);
with Source as TcxCustomLabelProperties do
begin
Self.LabelEffect := LabelEffect;
Self.LabelStyle := LabelStyle;
Self.Orientation := Orientation;
Self.Depth := Depth;
Self.ShadowedColor := ShadowedColor;
Self.Angle := Angle;
Self.PenWidth := PenWidth;
Self.Glyph := Glyph;
Self.ShowAccelChar := ShowAccelChar;
Self.WordWrap := WordWrap;
end;
finally
EndUpdate;
end
end
else
inherited Assign(Source);
end;
function TcxCustomLabelProperties.CanCompareEditValue: Boolean;
begin
Result := True;
end;
class function TcxCustomLabelProperties.GetContainerClass: TcxContainerClass;
begin
Result := TcxLabel;
end;
class function TcxCustomLabelProperties.GetStyleClass: TcxCustomEditStyleClass;
begin
Result := TcxLabelEditStyle;
end;
function TcxCustomLabelProperties.GetDisplayText(const AEditValue: TcxEditValue;
AFullText: Boolean = False; AIsInplace: Boolean = True): WideString;
var
ADisplayValue: TcxEditValue;
begin
PrepareDisplayValue(AEditValue, ADisplayValue, False);
Result := ADisplayValue;
end;
function TcxCustomLabelProperties.GetSupportedOperations: TcxEditSupportedOperations;
begin
Result := [esoAutoHeight, esoFiltering, esoShowingCaption, esoSorting,
esoTransparency];
end;
class function TcxCustomLabelProperties.GetViewInfoClass: TcxContainerViewInfoClass;
begin
Result := TcxCustomLabelViewInfo;
end;
function TcxCustomLabelProperties.IsEditValueValid(var EditValue: TcxEditValue; AEditFocused: Boolean): Boolean;
begin
Result := inherited IsEditValueValid(EditValue, AEditFocused);
end;
procedure TcxCustomLabelProperties.PrepareDisplayValue(const AEditValue:
TcxEditValue; var DisplayValue: TcxEditValue; AEditFocused: Boolean);
begin
DisplayValue := VarToStr(AEditValue);
end;
class function TcxCustomLabelProperties.GetViewDataClass: TcxCustomEditViewDataClass;
begin
Result := TcxCustomLabelViewData;
end;
function TcxCustomLabelProperties.HasDisplayValue: Boolean;
begin
Result := True;
end;
procedure TcxCustomLabelProperties.SetLabelEffect(Value : TcxLabelEffect);
begin
if FLabelEffect <> Value then
begin
FLabelEffect := Value;
Changed;
end;
end;
procedure TcxCustomLabelProperties.SetLabelStyle(Value : TcxLabelStyle);
begin
if FLabelStyle <> Value then
begin
FLabelStyle := Value;
Changed;
end;
end;
procedure TcxCustomLabelProperties.SetOrientation(Value : TcxLabelOrientation);
begin
if FOrientation <> Value then
begin
FOrientation := Value;
Changed;
end;
end;
procedure TcxCustomLabelProperties.SetDepth(Value : Word);
begin
if FDepth <> Value then
begin
FDepth := Value;
Changed;
end;
end;
procedure TcxCustomLabelProperties.SetShadowedColor(Value : TColor);
begin
if FShadowedColor <> Value then
begin
FShadowedColor := Value;
Changed;
end;
end;
procedure TcxCustomLabelProperties.SetAngle(Value: Integer);
begin
if FAngle <> Value then
begin
FAngle := Value;
Changed;
end;
end;
procedure TcxCustomLabelProperties.SetPenWidth(Value: Integer);
begin
if FPenWidth <> Value then
begin
FPenWidth := Value;
Changed;
end;
end;
function TcxCustomLabelProperties.GetGlyph: TBitmap;
begin
if FGlyph = nil then
begin
FGlyph := TBitmap.Create;
FGlyph.OnChange := GlyphChanged;
end;
Result := FGlyph;
end;
procedure TcxCustomLabelProperties.GlyphChanged(Sender: TObject);
begin
Changed;
end;
procedure TcxCustomLabelProperties.SetGlyph(Value: TBitmap);
begin
if Value = nil then
FreeAndNil(FGlyph)
else
Glyph.Assign(Value);
Changed;
end;
procedure TcxCustomLabelProperties.SetShowAccelChar(Value: Boolean);
begin
if FShowAccelChar <> Value then
begin
FShowAccelChar := Value;
Changed;
end;
end;
procedure TcxCustomLabelProperties.SetWordWrap(Value: Boolean);
begin
if FWordWrap <> Value then
begin
FWordWrap := Value;
Changed;
end;
end;
function TcxCustomLabelProperties.CalculateDepthDelta: TSize;
begin
Result.cx := 0;
Result.cy := 0;
if LabelEffect = cxleNormal then Exit;
case FOrientation of
cxoLeft, cxoRight: Result.cx := FDepth;
cxoTop, cxoBottom: Result.cy := FDepth;
cxoLeftTop, cxoLeftBottom, cxoRightTop, cxoRightBottom:
begin
Result.cx := FDepth;
Result.cy := FDepth;
end;
end;
end;
function TcxCustomLabelProperties.GetDisplayFormatOptions: TcxEditDisplayFormatOptions;
begin
Result := [];
end;
function TcxCustomLabelProperties.GetEditValueSource(AEditFocused: Boolean): TcxDataEditValueSource;
begin
Result := evsText;
end;
{ TcxCustomLabel }
destructor TcxCustomLabel.Destroy;
begin
FFocusControl := nil;
inherited Destroy;
end;
procedure TcxCustomLabel.Notification(ACOmponent: TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FFocusControl <> nil) and
(AComponent = FFocusControl) then FFocusControl := nil;
end;
class function TcxCustomLabel.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxCustomLabelProperties;
end;
procedure TcxCustomLabel.SetStyle(Value: TcxLabelEditStyle);
begin
FStyles.Style := Value;
end;
procedure TcxCustomLabel.Initialize;
begin
inherited Initialize;
ControlStyle := ControlStyle - [csCaptureMouse];
Width := 121;
Height := 21;
end;
procedure TcxCustomLabel.SetFocusControl(Value: TWinControl);
begin
if (FFocusControl <> Value) and (Value <> Self) then
FFocusControl := Value;
end;
procedure TcxCustomLabel.InternalSetEditValue(const Value: TcxEditValue;
AValidateEditValue: Boolean);
begin
inherited InternalSetEditValue(Value, AValidateEditValue);
if not FLockCaption then
Caption := VarToStr(Value);
SetInternalDisplayValue(Caption);
end;
function TcxCustomLabel.IsRightBoundFixed: Boolean;
var
AAlignment: TAlignment;
begin
Result := not (csReading in ComponentState);
if Result then
begin
AAlignment := ActiveProperties.Alignment.Horz;
if UseRightToLeftAlignment then
ChangeBiDiModeAlignment(AAlignment);
Result := AAlignment = taRightJustify;
end;
end;
procedure TcxCustomLabel.Loaded;
begin
if CanAllocateHandle(Self) then
HandleNeeded;
inherited Loaded;
end;
procedure TcxCustomLabel.SetInternalDisplayValue(Value: TcxEditValue);
begin
ViewInfo.Text := VarToStr(Value);
ShortRefreshContainer(False);
end;
procedure TcxCustomLabel.TextChanged;
begin
inherited TextChanged;
FLockCaption := True;
try
InternalEditValue := Caption;
finally
FLockCaption := False;
end;
end;
function TcxCustomLabel.CanFocus: Boolean;
begin
Result := IsInplace;
end;
{$IFDEF DELPHI10}
function TcxCustomLabel.GetTextBaseLine: Integer;
begin
Result := ViewInfo.GetTextBaseLine;
end;
function TcxCustomLabel.HasTextBaseLine: Boolean;
begin
Result := ActiveProperties.Angle = 0;
end;
{$ENDIF}
function TcxCustomLabel.CanAutoWidth: Boolean;
begin
Result := not ActiveProperties.WordWrap;
end;
function TcxCustomLabel.CanFocusOnClick: Boolean;
begin
Result := inherited CanFocusOnClick and IsInplace;
end;
function TcxCustomLabel.DefaultParentColor: Boolean;
begin
Result := True;
end;
procedure TcxCustomLabel.CMDialogChar(var Message: TCMDialogChar);
begin
if (FFocusControl <> nil) and Enabled and Properties.ShowAccelChar and
IsAccel(Message.CharCode, Caption) and FFocusControl.CanFocus then
begin
FFocusControl.SetFocus;
Message.Result := 1;
end;
end;
function TcxCustomLabel.GetProperties: TcxCustomLabelProperties;
begin
Result := TcxCustomLabelProperties(FProperties);
end;
function TcxCustomLabel.GetActiveProperties: TcxCustomLabelProperties;
begin
Result := TcxCustomLabelProperties(InternalGetActiveProperties);
end;
function TcxCustomLabel.GetStyle: TcxLabelEditStyle;
begin
Result := TcxLabelEditStyle(FStyles.Style);
end;
function TcxCustomLabel.GetViewInfo: TcxCustomLabelViewInfo;
begin
Result := TcxCustomLabelViewInfo(FViewInfo);
end;
procedure TcxCustomLabel.SetProperties(Value: TcxCustomLabelProperties);
begin
FProperties.Assign(Value);
end;
{ TcxLabel }
class function TcxLabel.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxLabelProperties;
end;
function TcxLabel.GetActiveProperties: TcxLabelProperties;
begin
Result := TcxLabelProperties(InternalGetActiveProperties);
end;
function TcxLabel.GetProperties: TcxLabelProperties;
begin
Result := TcxLabelProperties(FProperties);
end;
procedure TcxLabel.SetProperties(Value: TcxLabelProperties);
begin
FProperties.Assign(Value);
end;
initialization
GetRegisteredEditProperties.Register(TcxLabelProperties, scxSEditRepositoryLabelItem);
FilterEditsController.Register(TcxLabelProperties, TcxFilterTextEditHelper);
finalization
FilterEditsController.Unregister(TcxLabelProperties, TcxFilterTextEditHelper);
GetRegisteredEditProperties.Unregister(TcxLabelProperties);
end.