Chromium Code Reviews| Index: ui/views/cocoa/bridged_content_view.mm |
| diff --git a/ui/views/cocoa/bridged_content_view.mm b/ui/views/cocoa/bridged_content_view.mm |
| index 6be51fd9f5df3ad587c370c76d5a82fe0e12ee72..beec56a7c8ba85ba9da98ead538c06c8f58acb7c 100644 |
| --- a/ui/views/cocoa/bridged_content_view.mm |
| +++ b/ui/views/cocoa/bridged_content_view.mm |
| @@ -4,10 +4,15 @@ |
| #import "ui/views/cocoa/bridged_content_view.h" |
| +#include "base/strings/sys_string_conversions.h" |
| +#include "grit/ui_strings.h" |
| +#include "ui/base/ime/text_input_client.h" |
| #include "ui/gfx/mac/point_utils.h" |
| #include "ui/accessibility/ax_view_state.h" |
| #include "ui/gfx/canvas.h" |
| #include "ui/gfx/canvas_paint_mac.h" |
| +#include "ui/gfx/geometry/rect.h" |
| +#include "ui/gfx/mac/point_utils.h" |
| #include "ui/views/view.h" |
| #include "ui/views/widget/widget.h" |
| @@ -41,6 +46,10 @@ |
| hostedView_ = NULL; |
| } |
| +- (void)setTextInputClient:(ui::TextInputClient*)textInputClient { |
| + textInputClient_ = textInputClient; |
|
tapted
2014/06/17 13:23:56
Does toolkit-views guarantee to send OnDidChangeFo
Andre
2014/06/18 21:48:34
Yes, that should be handled through Widget::ViewHi
|
| +} |
| + |
| // BridgedContentView private implementation. |
| - (void)handleUntranslatedKeyEvent:(NSEvent*)theEvent { |
| @@ -59,8 +68,17 @@ |
| hostedView_->GetWidget()->OnMouseEvent(&event); |
| } |
| +- (void)doCommandByID:(int)cmd_id { |
|
tapted
2014/06/17 13:23:56
This should be declared in BridgedContentView () w
Andre
2014/06/18 21:48:34
Done.
|
| + if (textInputClient_ && textInputClient_->IsEditingCommandEnabled(cmd_id)) |
| + textInputClient_->ExecuteEditingCommand(cmd_id); |
| +} |
| + |
| // NSView implementation. |
| +- (BOOL)acceptsFirstResponder { |
| + return YES; |
| +} |
| + |
| - (void)setFrame:(NSRect)newFrame { |
| [super setFrame:newFrame]; |
| if (!hostedView_) |
| @@ -78,7 +96,10 @@ |
| } |
| - (void)keyDown:(NSEvent*)theEvent { |
| - [self handleUntranslatedKeyEvent:theEvent]; |
| + if (textInputClient_) |
| + [self interpretKeyEvents:@[ theEvent ]]; |
|
tapted
2014/06/17 13:23:56
Do you think interpretKeyEvents will be needed for
Andre
2014/06/18 21:48:35
If textInputClient_ is NULL, I think we should for
tapted
2014/06/19 01:29:15
yep - lg for now. For things like menus/lists we'l
|
| + else |
| + [self handleUntranslatedKeyEvent:theEvent]; |
| } |
| - (void)keyUp:(NSEvent*)theEvent { |
| @@ -97,4 +118,105 @@ |
| [self handleMouseEvent:theEvent]; |
| } |
| +- (void)deleteBackward:(id)sender { |
| + [self doCommandByID:IDS_DELETE_BACKWARD]; |
| +} |
| + |
| +- (void)deleteForward:(id)sender { |
| + [self doCommandByID:IDS_DELETE_FORWARD]; |
| +} |
| + |
| +- (void)moveLeft:(id)sender { |
| + [self doCommandByID:IDS_MOVE_LEFT]; |
| +} |
| + |
| +- (void)moveRight:(id)sender { |
| + [self doCommandByID:IDS_MOVE_RIGHT]; |
| +} |
| + |
| +// NSTextInputClient protocol implementation. |
| + |
| +- (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range |
|
tapted
2014/06/17 13:23:56
ugh longmethodnames. is this what clang-format doe
Andre
2014/06/18 21:48:34
Done.
|
| + actualRange:(NSRangePointer)actualRange { |
| + base::string16 text; |
|
tapted
2014/06/17 13:23:56
is there a better name for `text` - `substring` ma
Andre
2014/06/18 21:48:34
Done.
|
| + if (textInputClient_) { |
| + gfx::Range textRange; |
| + textInputClient_->GetTextRange(&textRange); |
| + gfx::Range subrange = textRange.Intersect(gfx::Range(range)); |
| + textInputClient_->GetTextFromRange(subrange, &text); |
| + if (actualRange) |
| + *actualRange = subrange.ToNSRange(); |
| + } |
| + return [[[NSAttributedString alloc] |
| + initWithString:base::SysUTF16ToNSString(text)] autorelease]; |
| +} |
| + |
| +- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { |
| + NOTIMPLEMENTED(); |
| + return 0; |
| +} |
| + |
| +- (void)doCommandBySelector:(SEL)selector { |
|
tapted
2014/06/17 13:23:56
Should be under `// NSResponder implementation.`.
Andre
2014/06/18 21:48:34
doCommandBySelector is part of both NSResponder an
tapted
2014/06/19 01:29:15
It's still overriding a method on NSResponder (whe
|
| + if ([self respondsToSelector:selector]) |
| + [self performSelector:selector withObject:nil]; |
| +} |
| + |
| +- (NSRect)firstRectForCharacterRange:(NSRange)range |
| + actualRange:(NSRangePointer)actualRange { |
| + // FIXME(andresantoso): ui::TextInputClient does not expose this. |
|
tapted
2014/06/17 13:23:56
I don't typically see FIXME comments. TODO is usua
Andre
2014/06/18 21:48:34
Yep, that was a temporary experiment.
I've changed
|
| + return textInputClient_ |
| + ? gfx::ScreenRectToNSRect(textInputClient_->GetCaretBounds()) |
| + : NSZeroRect; |
| +} |
| + |
| +- (BOOL)hasMarkedText { |
| + return textInputClient_ && textInputClient_->HasCompositionText(); |
| +} |
| + |
| +- (void)insertText:(id)text replacementRange:(NSRange)replacementRange { |
|
tapted
2014/06/17 13:23:56
nit: I think method signatures "always" linebreak
Andre
2014/06/18 21:48:34
Hmm, I don't see that in objcstyle, and cocoa code
tapted
2014/06/19 01:29:15
Oh wow - I've just always done it - but you're rig
|
| + if ([text isKindOfClass:[NSAttributedString class]]) |
|
tapted
2014/06/17 13:23:56
Before this, you should do
if (!textInputClient_)
Andre
2014/06/18 21:48:34
Done.
tapted
2014/06/19 01:29:15
`if (!textInputClient_)` should be the first line
Andre
2014/06/19 23:20:25
Done.
|
| + text = [text string]; |
| + if (textInputClient_) { |
| + textInputClient_->DeleteRange(gfx::Range(replacementRange)); |
| + textInputClient_->InsertText(base::SysNSStringToUTF16(text)); |
| + } |
| +} |
| + |
| +- (NSRange)markedRange { |
| + gfx::Range range; |
|
tapted
2014/06/17 13:23:56
if (!textInputClient_)
return NSMakeRange(0, 0);
Andre
2014/06/18 21:48:34
Done.
|
| + if (textInputClient_) |
| + textInputClient_->GetCompositionTextRange(&range); |
| + return range.ToNSRange(); |
| +} |
| + |
| +- (NSRange)selectedRange { |
| + gfx::Range range; |
| + if (textInputClient_) |
| + textInputClient_->GetSelectionRange(&range); |
| + return range.ToNSRange(); |
| +} |
| + |
| +- (void)setMarkedText:(id)text |
| + selectedRange:(NSRange)selectedRange |
| + replacementRange:(NSRange)replacementRange { |
| + if ([text isKindOfClass:[NSAttributedString class]]) |
| + text = [text string]; |
| + |
| + if (textInputClient_) { |
| + ui::CompositionText composition; |
| + composition.text = base::SysNSStringToUTF16(text); |
| + composition.selection = gfx::Range(selectedRange); |
| + textInputClient_->SetCompositionText(composition); |
| + } |
| +} |
| + |
| +- (void)unmarkText { |
| + if (textInputClient_) |
| + textInputClient_->ConfirmCompositionText(); |
| +} |
| + |
| +- (NSArray*)validAttributesForMarkedText { |
| + return @[]; |
| +} |
| + |
| @end |