Merge branch 'cocoa/control/textfield' into 'main'

FIX #39959: COCOA: TEdit (TCocoaTextField): line-breaks are not removed when pasting multi-line text, and offset display error

See merge request freepascal.org/lazarus/lazarus!118
This commit is contained in:
Maxim Ganetsky 2023-05-03 13:53:23 +00:00
commit a5d0de824e
3 changed files with 36 additions and 8 deletions

View File

@ -71,6 +71,7 @@ type
procedure resetCursorRects; override;
// key
procedure textDidChange(notification: NSNotification); override;
function textView_shouldChangeTextInRange_replacementString (textView: NSTextView; affectedCharRange: NSRange; replacementString: NSString): ObjCBOOL; message 'textView:shouldChangeTextInRange:replacementString:';
// mouse
procedure mouseDown(event: NSEvent); override;
procedure mouseUp(event: NSEvent); override;
@ -985,6 +986,24 @@ begin
callback.SendOnTextChanged;
end;
// detect and remove line-break when entering text
// TextField (TEdit) should be single line
function TCocoaTextField.textView_shouldChangeTextInRange_replacementString (textView: NSTextView; affectedCharRange: NSRange; replacementString: NSString): ObjCBOOL;
var
newString: NSString; // need not release
begin
Result:= true;
newString:= NSStringRemoveLineBreak( replacementString );
if newString.length <> replacementString.length then
begin
// only handled if there is line-break in replacementString
// use insertText() for undo/redo support
// textDidChange will be called in insertText()
if newString.length>0 then currentEditor.insertText( newString );
Result:= false;
end;
end;
procedure TCocoaTextField.mouseDown(event: NSEvent);
begin
if Assigned(callback) and not callback.MouseUpDownEvent(event) then

View File

@ -52,6 +52,8 @@ function StrToNSString(const s: string; AutoRelease: Boolean = true): NSString;
function StrToNSStr(const s: string; AutoRelease: Boolean = true): NSString; inline;
function NSStringToString(ns: NSString): String;
function NSStringRemoveLineBreak(const str: NSString): NSString;
function GetNSObjectWindow(obj: NSObject): NSWindow;
procedure SetNSText(text: NSText; const s: String); inline;
@ -831,6 +833,12 @@ begin
Result := CFStringToStr(CFStringRef(ns));
end;
function NSStringRemoveLineBreak(const str: NSString): NSString;
begin
Result:= str.stringByReplacingOccurrencesOfString_withString( NSStr(#10) , NSString.string_ );
Result:= Result.stringByReplacingOccurrencesOfString_withString( NSStr(#13), NSString.string_ );
end;
procedure SetNSText(text: NSText; const s: String); inline;
var
ns: NSString;

View File

@ -990,7 +990,6 @@ begin
cell := NSTextFieldCell(field.cell);
cell.setWraps(false);
cell.setScrollable(true);
cell.setUsesSingleLineMode(true);
end;
TextFieldSetAllignment(field, TCustomEdit(AWinControl).Alignment);
TextFieldSetBorderStyle(field, TCustomEdit(AWinControl).BorderStyle);
@ -1213,16 +1212,18 @@ end;
class procedure TCocoaWSCustomEdit.SetText(const AWinControl: TWinControl;
const AText: String);
var
txt : string;
mxl : Integer;
txt : NSString; // NSString for AText
txtWithLineBreak: NSString; // need not release
field: TCocoaTextField;
begin
if (AWinControl.HandleAllocated) then
begin
txt := AText;
mxl := TCustomEdit(AWinControl).MaxLength;
if (mxl > 0) and (UTF8Length(txt) > mxl) then
txt := UTF8Copy(txt, 1, mxl);
ControlSetTextWithChangeEvent(NSControl(AWinControl.Handle), txt);
field:= TCocoaTextField(AWinControl.Handle);
txt:= NSStringUtf8(AText);
txtWithLineBreak := NSStringRemoveLineBreak(txt);
field.setStringValue(txtWithLineBreak);
field.textDidChange(nil); // check maxLength and calls controls callback (if any)
txt.release;
end;
end;