mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-16 04:19:19 +02:00
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:
parent
af9d15b12b
commit
e55401e29b
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user