mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-31 01:12:57 +02:00
Cocoa: IME: implements a base NSTextInputClient for non-editable LCL CustomControl
implements a base NSTextInputClient for non-editable LCL CustomControl, like Form, Grid, ListView, that are not system control and not FullEditControl. 1. when using IME in these controls, a temporary and one-time editor is shown at the bottom of the control, supporting IME such as Chinese. 2. refers to MacOS Finder, when using IME in the file list view, a small window will pop up at the bottom of the screen for input. the text can then be used for filename starting character match. 3. it is useful for implementing IME support for controls that do not have a text input window.
This commit is contained in:
parent
873c352755
commit
7031b6b752
@ -203,6 +203,8 @@ type
|
||||
|
||||
isdrawing : integer;
|
||||
faileddraw : Boolean;
|
||||
|
||||
_inIME: Boolean;
|
||||
public
|
||||
callback: ICommonCallback;
|
||||
auxMouseByParent: Boolean;
|
||||
@ -234,9 +236,19 @@ type
|
||||
function stringValue: NSString; override;
|
||||
procedure addSubView(aview: NSView); override;
|
||||
|
||||
// this is parts of
|
||||
public
|
||||
// NSTextInputClientProtocol related.
|
||||
// implements a base NSTextInputClient for non-editable LCL CustomControl,
|
||||
// like Form, Grid, ListView, that are not system control and not FullEditControl.
|
||||
// 1. when using IME in these controls, a temporary and one-time editor is shown
|
||||
// at the bottom of the control, supporting IME such as Chinese.
|
||||
// 2. refers to MacOS Finder, when using IME in the file list view,
|
||||
// a small window will pop up at the bottom of the screen for input.
|
||||
// the text can then be used for filename starting character match.
|
||||
// 3. it is useful for implementing IME support for controls that do not
|
||||
// have a text input window.
|
||||
procedure keyDown(theEvent: NSEvent); override;
|
||||
procedure insertText_replacementRange (aString: id; replacementRange: NSRange);
|
||||
procedure doCommandBySelector (aSelector: SEL); override;
|
||||
procedure setMarkedText_selectedRange_replacementRange (aString: id; selectedRange: NSRange; replacementRange: NSRange);
|
||||
procedure unmarkText;
|
||||
function selectedRange: NSRange;
|
||||
@ -246,6 +258,7 @@ type
|
||||
function validAttributesForMarkedText: NSArray;
|
||||
function firstRectForCharacterRange_actualRange (aRange: NSRange; actualRange: NSRangePointer): NSRect;
|
||||
function characterIndexForPoint (aPoint: NSPoint): NSUInteger;
|
||||
procedure doCommandBySelector (aSelector: SEL); override;
|
||||
end;
|
||||
|
||||
{ ICocoaIMEControl }
|
||||
@ -585,6 +598,14 @@ end;
|
||||
|
||||
{ TCocoaCustomControl }
|
||||
|
||||
function getNSStringObject( const aString: id ) : NSString;
|
||||
begin
|
||||
if aString.isKindOfClass( NSAttributedString.classClass ) then
|
||||
Result:= NSAttributedString( aString ).string_
|
||||
else
|
||||
Result:= NSString( aString );
|
||||
end;
|
||||
|
||||
procedure TCocoaCustomControl.setStringValue(avalue: NSString);
|
||||
begin
|
||||
if Assigned(fstr) then fstr.release;
|
||||
@ -617,25 +638,78 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCocoaCustomControl.insertText_replacementRange(aString: id;
|
||||
replacementRange: NSRange);
|
||||
procedure TCocoaCustomControl.keyDown(theEvent: NSEvent);
|
||||
var
|
||||
view: NSView;
|
||||
isFirst: Boolean;
|
||||
begin
|
||||
lclGetCallback.InputClientInsertText(NSStringToString(NSString(astring)));
|
||||
isFirst:= not _inIME;
|
||||
inputContext.handleEvent(theEvent);
|
||||
if _inIME and isFirst then
|
||||
begin
|
||||
view:= self.window.fieldEditor_forObject(true, nil);
|
||||
view.setFrameSize( NSMakeSize(self.frame.size.width,16) );
|
||||
self.addSubView( view );
|
||||
end
|
||||
else if not _inIME then
|
||||
inputContext.discardMarkedText;
|
||||
end;
|
||||
|
||||
procedure TCocoaCustomControl.doCommandBySelector(aSelector: SEL);
|
||||
procedure TCocoaCustomControl.insertText_replacementRange(aString: id;
|
||||
replacementRange: NSRange);
|
||||
var
|
||||
textView: NSTextView;
|
||||
nsText: NSString;
|
||||
begin
|
||||
inherited doCommandBySelector(ASelector);
|
||||
if not _inIME then exit;
|
||||
|
||||
textView:= NSTextView(self.window.fieldEditor_forObject(false,nil));
|
||||
if Assigned(textView) then
|
||||
textView.removeFromSuperview;
|
||||
|
||||
nsText:= getNSStringObject(aString);
|
||||
lclGetCallback.InputClientInsertText(nsText.UTF8String);
|
||||
|
||||
unmarkText;
|
||||
end;
|
||||
|
||||
procedure TCocoaCustomControl.setMarkedText_selectedRange_replacementRange(
|
||||
aString: id; selectedRange: NSRange; replacementRange: NSRange);
|
||||
var
|
||||
textView: NSTextView;
|
||||
nsText: NSString;
|
||||
begin
|
||||
nsText:= getNSStringObject(aString);
|
||||
if nsText.length > 0 then
|
||||
begin
|
||||
_inIME:= true;
|
||||
textView:= NSTextView(self.window.fieldEditor_forObject(false,nil));
|
||||
if Assigned(textView) then
|
||||
textView.setMarkedText_selectedRange_replacementRange(aString,selectedRange,replacementRange);
|
||||
end
|
||||
else
|
||||
unmarkText;
|
||||
end;
|
||||
|
||||
function TCocoaCustomControl.hasMarkedText: LCLObjCBoolean;
|
||||
begin
|
||||
Result := _inIME;
|
||||
end;
|
||||
|
||||
procedure TCocoaCustomControl.unmarkText;
|
||||
begin
|
||||
_inIME:= false;
|
||||
end;
|
||||
|
||||
function TCocoaCustomControl.firstRectForCharacterRange_actualRange(
|
||||
aRange: NSRange; actualRange: NSRangePointer): NSRect;
|
||||
var
|
||||
point: NSPoint;
|
||||
rect: NSRect;
|
||||
begin
|
||||
point:= self.convertPoint_toView(NSZeroPoint, nil);
|
||||
rect:= NSMakeRect(point.x, point.y, 0, 16);
|
||||
Result:= self.window.convertRectToScreen(rect);
|
||||
end;
|
||||
|
||||
function TCocoaCustomControl.selectedRange: NSRange;
|
||||
@ -648,11 +722,6 @@ begin
|
||||
Result := NSMakeRange(0,0);
|
||||
end;
|
||||
|
||||
function TCocoaCustomControl.hasMarkedText: LCLObjCBoolean;
|
||||
begin
|
||||
Result := false;
|
||||
end;
|
||||
|
||||
function TCocoaCustomControl.attributedSubstringForProposedRange_actualRange(
|
||||
aRange: NSRange; actualRange: NSRangePointer): NSAttributedString;
|
||||
begin
|
||||
@ -664,18 +733,17 @@ begin
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
function TCocoaCustomControl.firstRectForCharacterRange_actualRange(
|
||||
aRange: NSRange; actualRange: NSRangePointer): NSRect;
|
||||
begin
|
||||
Result := NSMakeRect(0,0,0,0);
|
||||
end;
|
||||
|
||||
function TCocoaCustomControl.characterIndexForPoint(aPoint: NSPoint
|
||||
): NSUInteger;
|
||||
begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
procedure TCocoaCustomControl.doCommandBySelector(aSelector: SEL);
|
||||
begin
|
||||
inherited doCommandBySelector(ASelector);
|
||||
end;
|
||||
|
||||
procedure TCocoaCustomControl.dealloc;
|
||||
begin
|
||||
if Assigned(fstr) then fstr.release;
|
||||
@ -916,14 +984,6 @@ begin
|
||||
Result := not hasMarkedText();
|
||||
end;
|
||||
|
||||
function getNSStringObject( const aString: id ) : NSString;
|
||||
begin
|
||||
if aString.isKindOfClass( NSAttributedString.classClass ) then
|
||||
Result:= NSAttributedString( aString ).string_
|
||||
else
|
||||
Result:= NSString( aString );
|
||||
end;
|
||||
|
||||
function isIMEDuplicateCall( const newParams, currentParams: TCocoaIMEParameters ) : Boolean;
|
||||
begin
|
||||
Result:= false;
|
||||
|
Loading…
Reference in New Issue
Block a user