customdrawn: Many fixes and improvements for TCDEdit, now VK_HOME and VK_END are supported

git-svn-id: trunk@33614 -
This commit is contained in:
sekelsenmat 2011-11-18 14:49:59 +00:00
parent af9d15b12b
commit e55401e29b
5 changed files with 133 additions and 16 deletions

View File

@ -55,6 +55,8 @@ type
// TCDEdit
procedure DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
AState: TCDControlState; AStateEx: TCDEditStateEx); override;
procedure DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
AState: TCDControlState; AStateEx: TCDEditStateEx); override;
procedure DrawCaret(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
AState: TCDControlState; AStateEx: TCDEditStateEx); override;
procedure DrawEdit(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
@ -137,7 +139,7 @@ end;
function TCDDrawerCommon.GetMeasures(AMeasureID: Integer): Integer;
begin
case AMeasureID of
TCDEDIT_LEFT_TEXT_SPACING: Result := 4;
TCDEDIT_LEFT_TEXT_SPACING: Result := 6;
TCDEDIT_RIGHT_TEXT_SPACING: Result := 3;
TCDEDIT_TOP_TEXT_SPACING: Result := 3;
TCDEDIT_BOTTOM_TEXT_SPACING: Result := 3;
@ -612,9 +614,14 @@ begin
ADest.Pen.Color := WIN2000_FRAME_WHITE;
ADest.Pen.Style := psSolid;
ADest.Rectangle(0, 0, ASize.cx, ASize.cy);
end;
procedure TCDDrawerCommon.DrawEditFrame(ADest: TCanvas; ADestPos: TPoint;
ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx);
begin
// The Frame, except the lower-bottom which is white anyway
// outter top-right
ADest.Pen.Style := psSolid;
ADest.Pen.Color := WIN2000_FRAME_GRAY;
ADest.MoveTo(0, ASize.cy-1);
ADest.LineTo(0, 0);
@ -644,8 +651,9 @@ begin
lCaptionHeight := GetMeasuresEx(ADest, TCDCONTROL_CAPTION_HEIGHT, AState, AStateEx);
lTextTopSpacing := GetMeasures(TCDEDIT_TOP_TEXT_SPACING);
lTmpText := UTF8Copy(lControlText, 1, AStateEx.CaretPos.X-AStateEx.VisibleTextStart.X+1);
lCaretPixelPos := ADest.TextWidth(lTmpText) + 3;
lTmpText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, AStateEx.CaretPos.X-AStateEx.VisibleTextStart.X+1);
lCaretPixelPos := ADest.TextWidth(lTmpText) + GetMeasures(TCDEDIT_LEFT_TEXT_SPACING)
+ AStateEx.LeftTextMargin;
ADest.Pen.Color := clBlack;
ADest.Pen.Style := psSolid;
ADest.Line(lCaretPixelPos, lTextTopSpacing, lCaretPixelPos, lTextTopSpacing+lCaptionHeight);
@ -672,7 +680,7 @@ begin
lTextTopSpacing := GetMeasures(TCDEDIT_TOP_TEXT_SPACING);
lTextBottomSpacing := GetMeasures(TCDEDIT_BOTTOM_TEXT_SPACING);
// The text without selection
// The text
ADest.Pen.Style := psClear;
if AStateEx.SelLength = 0 then
begin
@ -684,14 +692,19 @@ begin
begin
lSelLeftPos := AStateEx.SelStart.X;
if AStateEx.SelLength < 0 then lSelLeftPos := lSelLeftPos + AStateEx.SelLength;
lSelLeftPos := lSelLeftPos + AStateEx.VisibleTextStart.X-1;
lSelRightPos := AStateEx.SelStart.X;
if AStateEx.SelLength > 0 then lSelRightPos := lSelRightPos + AStateEx.SelLength;
lSelRightPos := lSelRightPos + AStateEx.VisibleTextStart.X-1;
lSelLength := AStateEx.SelLength;
if lSelLength < 0 then lSelLength := lSelLength * -1;
lSelLength := lSelLength - (AStateEx.VisibleTextStart.X-1);
// Text left of the selection
lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lSelLeftPos-AStateEx.VisibleTextStart.X+1);
ADest.TextOut(4, lTextTopSpacing, lVisibleText);
ADest.TextOut(lTextLeftSpacing, lTextTopSpacing, lVisibleText);
lSelLeftPixelPos := ADest.TextWidth(lVisibleText)+lTextLeftSpacing;
// The selection background
@ -716,6 +729,9 @@ begin
// And the caret
DrawCaret(ADest, ADestPos, ASize, AState, AStateEx);
// In the end the frame, because it must be on top of everything
DrawEditFrame(ADest, ADestPos, ASize, AState, AStateEx);
end;
procedure TCDDrawerCommon.DrawCheckBoxSquare(ADest: TCanvas; ADestPos: TPoint;

View File

@ -34,7 +34,7 @@ type
procedure DrawButton(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
AState: TCDControlState; AStateEx: TCDButtonStateEx); override;
// TCDEdit
procedure DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
procedure DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
AState: TCDControlState; AStateEx: TCDEditStateEx); override;
procedure DrawCaret(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
AState: TCDControlState; AStateEx: TCDEditStateEx); override;
@ -121,12 +121,11 @@ begin
(ASize.cy - ADest.TextHeight(Str)) div 2, Str);
end;
procedure TCDDrawerWinCE.DrawEditBackground(ADest: TCanvas; ADestPos: TPoint;
procedure TCDDrawerWinCE.DrawEditFrame(ADest: TCanvas; ADestPos: TPoint;
ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx);
begin
// The background
ADest.Brush.Color := clWhite;
ADest.Brush.Style := bsSolid;
// The frame
ADest.Brush.Style := bsClear;
ADest.Pen.Color := clBlack;
ADest.Pen.Style := psSolid;
ADest.Rectangle(0, 0, ASize.cx, ASize.cy);

View File

@ -41,7 +41,7 @@ type
procedure DrawButton(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
AState: TCDControlState; AStateEx: TCDButtonStateEx); override;
// TCDEdit
procedure DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
procedure DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
AState: TCDControlState; AStateEx: TCDEditStateEx); override;
// TCDCheckBox
procedure DrawCheckBoxSquare(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
@ -176,12 +176,11 @@ begin
(ASize.cy - ADest.TextHeight(Str)) div 2, Str);
end;
procedure TCDDrawerWinXP.DrawEditBackground(ADest: TCanvas; ADestPos: TPoint;
procedure TCDDrawerWinXP.DrawEditFrame(ADest: TCanvas; ADestPos: TPoint;
ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx);
begin
// The background
ADest.Brush.Color := clWhite;
ADest.Brush.Style := bsSolid;
// The frame
ADest.Brush.Style := bsClear;
ADest.Pen.Color := WINXP_FRAME_BLUE;
ADest.Pen.Style := psSolid;
ADest.Rectangle(0, 0, ASize.cx, ASize.cy);

View File

@ -146,6 +146,7 @@ type
property Enabled;
property Font;
property Glyph: TBitmap read FGlyph write SetGlyph;
// property IsToggleBox: Boolean read FGlyph write SetGlyph;
property OnChangeBounds;
property OnClick;
property OnContextPopup;
@ -181,11 +182,15 @@ type
DragDropStarted: boolean;
FCaretTimer: TTimer;
FEditState: TCDEditStateEx; // Points to the same object as FStateEx, so don't Free!
function GetLeftTextMargin: Integer;
function GetRightTextMargin: Integer;
procedure HandleCaretTimer(Sender: TObject);
procedure DoDeleteSelection;
procedure DoClearSelection;
procedure DoManageVisibleTextStart;
function GetText: string;
procedure SetLeftTextMargin(AValue: Integer);
procedure SetRightTextMargin(AValue: Integer);
procedure SetText(AValue: string);
function MousePosToCaretPos(X, Y: Integer): TPoint;
function IsSomethingSelected: Boolean;
@ -208,6 +213,8 @@ type
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property LeftTextMargin: Integer read GetLeftTextMargin write SetLeftTextMargin;
property RightTextMargin: Integer read GetRightTextMargin write SetRightTextMargin;
published
property Align;
property Anchors;
@ -1036,6 +1043,20 @@ begin
Result := Caption;
end;
procedure TCDEdit.SetLeftTextMargin(AValue: Integer);
begin
if FEditState.LeftTextMargin = AValue then Exit;
FEditState.LeftTextMargin := AValue;
Invalidate;
end;
procedure TCDEdit.SetRightTextMargin(AValue: Integer);
begin
if FEditState.RightTextMargin = AValue then Exit;
FEditState.RightTextMargin := AValue;
Invalidate;
end;
function TCDEdit.GetControlId: TCDControlID;
begin
Result := cidEdit;
@ -1059,6 +1080,16 @@ begin
Invalidate;
end;
function TCDEdit.GetLeftTextMargin: Integer;
begin
Result := FEditState.LeftTextMargin;
end;
function TCDEdit.GetRightTextMargin: Integer;
begin
Result := FEditState.RightTextMargin;
end;
procedure TCDEdit.DoDeleteSelection;
var
lSelLeftPos, lSelRightPos, lSelLength: Integer;
@ -1111,7 +1142,7 @@ begin
- FDrawer.GetMeasures(TCDEDIT_LEFT_TEXT_SPACING)
- FDrawer.GetMeasures(TCDEDIT_RIGHT_TEXT_SPACING);
lVisibleTextCharCount := Canvas.TextFitInfo(lText, lAvailableWidth);
FEditState.VisibleTextStart.X := Max(FEditState.CaretPos.X-lVisibleTextCharCount, FEditState.VisibleTextStart.X);
FEditState.VisibleTextStart.X := Max(FEditState.CaretPos.X-lVisibleTextCharCount+1, FEditState.VisibleTextStart.X);
end;
procedure TCDEdit.SetText(AValue: string);
@ -1241,6 +1272,42 @@ begin
DoManageVisibleTextStart();
FEditState.CaretIsVisible := True;
Invalidate;
end
// if we are not moving, at least deselect
else if ([ssShift] <> Shift) then
begin
FEditState.SelLength := 0;
Invalidate;
end;
end;
VK_HOME:
begin
if (FEditState.CaretPos.X > 0) then
begin
// Selecting to the left
if [ssShift] = Shift then
begin
if FEditState.SelLength = 0 then
begin
FEditState.SelStart.X := FEditState.CaretPos.X;
FEditState.SelLength := -1 * FEditState.CaretPos.X;
end
else
FEditState.SelLength := -1 * FEditState.SelStart.X;
end
// Normal move to the left
else FEditState.SelLength := 0;
FEditState.CaretPos.X := 0;
DoManageVisibleTextStart();
FEditState.CaretIsVisible := True;
Invalidate;
end
// if we are not moving, at least deselect
else if (FEditState.SelLength <> 0) and ([ssShift] <> Shift) then
begin
FEditState.SelLength := 0;
Invalidate;
end;
end;
VK_RIGHT:
@ -1260,6 +1327,38 @@ begin
DoManageVisibleTextStart();
FEditState.CaretIsVisible := True;
Invalidate;
end
// if we are not moving, at least deselect
else if ([ssShift] <> Shift) then
begin
FEditState.SelLength := 0;
Invalidate;
end;
end;
VK_END:
begin
if FEditState.CaretPos.X < lOldTextLength then
begin
// Selecting to the right
if [ssShift] = Shift then
begin
if FEditState.SelLength = 0 then
FEditState.SelStart.X := FEditState.CaretPos.X;
FEditState.SelLength := lOldTextLength - FEditState.SelStart.X;
end
// Normal move to the right
else FEditState.SelLength := 0;
FEditState.CaretPos.X := lOldTextLength;
DoManageVisibleTextStart();
FEditState.CaretIsVisible := True;
Invalidate;
end
// if we are not moving, at least deselect
else if (FEditState.SelLength <> 0) and ([ssShift] <> Shift) then
begin
FEditState.SelLength := 0;
Invalidate;
end;
end;

View File

@ -148,6 +148,8 @@ type
SelLength: Integer; // zero means no selection. Negative numbers selection to the left from the start and positive ones to the right
VisibleTextStart: TPoint; // X is 1-based
EventArrived: Boolean; // Added by event handlers and used by the caret so that it stops blinking while events are incoming
// customizable extra margins, zero is the base value
LeftTextMargin, RightTextMargin: Integer;
end;
TCDPositionedCStateEx = class(TCDControlStateEx)
@ -288,6 +290,8 @@ type
// TCDEdit
procedure DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
AState: TCDControlState; AStateEx: TCDEditStateEx); virtual; abstract;
procedure DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
AState: TCDControlState; AStateEx: TCDEditStateEx); virtual; abstract;
procedure DrawCaret(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
AState: TCDControlState; AStateEx: TCDEditStateEx); virtual; abstract;
procedure DrawEdit(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;