mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-19 23:49:36 +02:00
customdrawn: Many fixes and improvements to the caret, selection and mouse selection in TCDEdit
git-svn-id: trunk@33312 -
This commit is contained in:
parent
328267f217
commit
d19fefdef5
@ -366,12 +366,12 @@ begin
|
||||
if lSelLength < 0 then lSelLength := lSelLength * -1;
|
||||
|
||||
// Text left of the selection
|
||||
lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart, lSelLeftPos-AStateEx.VisibleTextStart);
|
||||
lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart, lSelLeftPos-AStateEx.VisibleTextStart+1);
|
||||
ADest.TextOut(4, lTextTopSpacing, lVisibleText);
|
||||
lSelLeftPixelPos := ADest.TextWidth(lVisibleText)+lTextLeftSpacing;
|
||||
|
||||
// The selection background
|
||||
lVisibleText := UTF8Copy(lControlText, lSelLeftPos, lSelLength);
|
||||
lVisibleText := UTF8Copy(lControlText, lSelLeftPos+1, lSelLength);
|
||||
lTextWidth := ADest.TextWidth(lVisibleText);
|
||||
ADest.Brush.Color := clBlue;
|
||||
ADest.Brush.Style := bsSolid;
|
||||
|
@ -151,6 +151,7 @@ type
|
||||
procedure DoManageVisibleTextStart;
|
||||
function GetText: string;
|
||||
procedure SetText(AValue: string);
|
||||
function MousePosToCaretPos(X, Y: Integer): Integer;
|
||||
protected
|
||||
// keyboard
|
||||
procedure DoEnter; override;
|
||||
@ -442,7 +443,13 @@ end;
|
||||
|
||||
procedure TCDEdit.HandleCaretTimer(Sender: TObject);
|
||||
begin
|
||||
FEditState.CaretIsVisible := not FEditState.CaretIsVisible;
|
||||
if FEditState.EventArrived then
|
||||
begin
|
||||
FEditState.CaretIsVisible := True;
|
||||
FEditState.EventArrived := False;
|
||||
end
|
||||
else FEditState.CaretIsVisible := not FEditState.CaretIsVisible;
|
||||
|
||||
Invalidate;
|
||||
end;
|
||||
|
||||
@ -475,6 +482,46 @@ begin
|
||||
Caption := AValue;
|
||||
end;
|
||||
|
||||
// returns a zero-based position of the caret
|
||||
function TCDEdit.MousePosToCaretPos(X, Y: Integer): Integer;
|
||||
var
|
||||
lStrLen, i: PtrInt;
|
||||
lVisibleStr, lCurChar: String;
|
||||
lPos, lCurCharLen: Integer;
|
||||
lBestDiff: Cardinal = $FFFFFFFF;
|
||||
lLastDiff: Cardinal = $FFFFFFFF;
|
||||
lCurDiff, lBestMatch: Integer;
|
||||
begin
|
||||
Canvas.Font := Font;
|
||||
lVisibleStr := UTF8Copy(Text, FEditState.VisibleTextStart, Length(Text));
|
||||
lStrLen := UTF8Length(lVisibleStr);
|
||||
lPos := FDrawer.GetMeasures(TCDEDIT_LEFT_TEXT_SPACING);
|
||||
for i := 0 to lStrLen do
|
||||
begin
|
||||
lCurDiff := X - lPos;
|
||||
if lCurDiff < 0 then lCurDiff := lCurDiff * -1;
|
||||
|
||||
if lCurDiff < lBestDiff then
|
||||
begin
|
||||
lBestDiff := lCurDiff;
|
||||
lBestMatch := i;
|
||||
end;
|
||||
|
||||
// When the diff starts to grow we already found the caret pos, so exit
|
||||
if lCurDiff > lLastDiff then Exit(lBestMatch)
|
||||
else lLastDiff := lCurDiff;
|
||||
|
||||
if i <> lStrLen then
|
||||
begin
|
||||
lCurChar := UTF8Copy(lVisibleStr, i+1, 1);
|
||||
lCurCharLen := Canvas.TextWidth(lCurChar);
|
||||
lPos := lPos + lCurCharLen;
|
||||
end;
|
||||
end;
|
||||
|
||||
Exit(lBestMatch);
|
||||
end;
|
||||
|
||||
procedure TCDEdit.DoEnter;
|
||||
begin
|
||||
inherited DoEnter;
|
||||
@ -497,6 +544,7 @@ procedure TCDEdit.KeyDown(var Key: word; Shift: TShiftState);
|
||||
var
|
||||
lLeftText, lRightText, lOldText: String;
|
||||
lOldTextLength: PtrInt;
|
||||
lKeyWasProcessed: Boolean = True;
|
||||
begin
|
||||
inherited KeyDown(Key, Shift);
|
||||
|
||||
@ -541,10 +589,10 @@ begin
|
||||
if (FEditState.CaretPos > 0) then
|
||||
begin
|
||||
// Selecting to the left
|
||||
if ssShift in Shift then
|
||||
if [ssShift] = Shift then
|
||||
begin
|
||||
if FEditState.SelLength = 0 then FEditState.SelStart := FEditState.CaretPos;
|
||||
Dec(FEditState.SelLength);
|
||||
if FEditState.SelStart < 0 then FEditState.SelStart := FEditState.CaretPos;
|
||||
end
|
||||
// Normal move to the left
|
||||
else FEditState.SelLength := 0;
|
||||
@ -560,10 +608,10 @@ begin
|
||||
if FEditState.CaretPos < lOldTextLength then
|
||||
begin
|
||||
// Selecting to the right
|
||||
if ssShift in Shift then
|
||||
if [ssShift] = Shift then
|
||||
begin
|
||||
if FEditState.SelLength = 0 then FEditState.SelStart := FEditState.CaretPos;
|
||||
Inc(FEditState.SelLength);
|
||||
if FEditState.SelStart < 0 then FEditState.SelStart := FEditState.CaretPos;
|
||||
end
|
||||
// Normal move to the right
|
||||
else FEditState.SelLength := 0;
|
||||
@ -575,7 +623,11 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
else
|
||||
lKeyWasProcessed := False;
|
||||
end; // case
|
||||
|
||||
if lKeyWasProcessed then FEditState.EventArrived := True;
|
||||
end;
|
||||
|
||||
procedure TCDEdit.KeyUp(var Key: word; Shift: TShiftState);
|
||||
@ -601,6 +653,7 @@ begin
|
||||
lRightText := UTF8Copy(lOldText, FEditState.CaretPos+1, UTF8Length(lOldText));
|
||||
Text := lLeftText + UTF8Key + lRightText;
|
||||
Inc(FEditState.CaretPos);
|
||||
FEditState.EventArrived := True;
|
||||
FEditState.CaretIsVisible := True;
|
||||
Invalidate;
|
||||
end;
|
||||
@ -609,17 +662,37 @@ procedure TCDEdit.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
|
||||
Y: integer);
|
||||
begin
|
||||
inherited MouseDown(Button, Shift, X, Y);
|
||||
DragDropStarted := True;
|
||||
|
||||
// Caret positioning
|
||||
FEditState.CaretPos := MousePosToCaretPos(X, Y);
|
||||
FEditState.SelLength := 0;
|
||||
FEditState.SelStart := FEditState.CaretPos;
|
||||
FEditState.EventArrived := True;
|
||||
FEditState.CaretIsVisible := True;
|
||||
Invalidate;
|
||||
end;
|
||||
|
||||
procedure TCDEdit.MouseMove(Shift: TShiftState; X, Y: integer);
|
||||
begin
|
||||
inherited MouseMove(Shift, X, Y);
|
||||
|
||||
// Mouse dragging selection
|
||||
if DragDropStarted then
|
||||
begin
|
||||
FEditState.CaretPos := MousePosToCaretPos(X, Y);
|
||||
FEditState.SelLength := FEditState.CaretPos - FEditState.SelStart;
|
||||
FEditState.EventArrived := True;
|
||||
FEditState.CaretIsVisible := True;
|
||||
Invalidate;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCDEdit.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
|
||||
Y: integer);
|
||||
begin
|
||||
inherited MouseUp(Button, Shift, X, Y);
|
||||
DragDropStarted := False;
|
||||
end;
|
||||
|
||||
procedure TCDEdit.MouseEnter;
|
||||
@ -642,7 +715,6 @@ begin
|
||||
|
||||
// State information
|
||||
FEditState.VisibleTextStart := 1;
|
||||
FEditState.SelStart := -1;
|
||||
|
||||
// Caret code
|
||||
FCaretTimer := TTimer.Create(Self);
|
||||
|
@ -108,6 +108,7 @@ type
|
||||
SelStart: Integer; // zero-based position
|
||||
SelLength: Integer; // zero means no selection. Negative numbers selection to the left from the start and positive ones to the right
|
||||
VisibleTextStart: Integer; // 1-based
|
||||
EventArrived: Boolean; // Added by event handlers and used by the caret so that it stops blinking while events are incoming
|
||||
end;
|
||||
|
||||
TCDTrackBarStateEx = class(TCDControlStateEx)
|
||||
|
Loading…
Reference in New Issue
Block a user